修复游戏详情闪退问题
This commit is contained in:
@ -12,48 +12,48 @@ import android.text.style.ClickableSpan;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
|
||||
public class ExpandTextView extends AppCompatTextView {
|
||||
|
||||
|
||||
private CharSequence mSnapshotText;
|
||||
|
||||
|
||||
private String mEndText = "...";
|
||||
private String mExpandText = mEndText + "全文";
|
||||
private boolean mUseGradientAlphaEndText = false;
|
||||
private boolean mShrinkOnAnchor = false; // 以锚点所在的位置进行收起 (即 maxLines = 锚点所在的行)
|
||||
|
||||
|
||||
private int mMaxLines = 3; // 由于sdk版本限制(getMaxLines) 这里设置默认值
|
||||
|
||||
|
||||
private boolean mInitLayout = false;
|
||||
private boolean mIsExpanded = false; // 位于 recyclerView 时需要自行在外层管理是否已展开
|
||||
|
||||
|
||||
private ExpandCallback mExpandCallback;
|
||||
private SelfCalculateMaxLinesCallback mMaxLinesCalculatedCallback;
|
||||
|
||||
|
||||
private Rect mLastVisibleLineRect;
|
||||
private Rect mLastActualLineRect;
|
||||
|
||||
|
||||
private static int DEFAULT_ADDITIONAL_END_TEXT_COUNT = 2;
|
||||
public static final String SHRINK_ANCHOR = "☼";
|
||||
|
||||
|
||||
public ExpandTextView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
|
||||
public ExpandTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
mMaxLines = getMaxLines();
|
||||
}
|
||||
|
||||
|
||||
mLastVisibleLineRect = new Rect();
|
||||
mLastActualLineRect = new Rect();
|
||||
|
||||
|
||||
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ExpandTextView);
|
||||
mShrinkOnAnchor = ta.getBoolean(R.styleable.ExpandTextView_shrinkOnAnchor, false);
|
||||
mUseGradientAlphaEndText = ta.getBoolean(R.styleable.ExpandTextView_useGradientAlphaEndText, false);
|
||||
@ -62,7 +62,7 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
.getString(R.styleable.ExpandTextView_expandText);
|
||||
ta.recycle();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
@ -71,7 +71,7 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
}
|
||||
setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() - getExtraBottomPadding());
|
||||
}
|
||||
|
||||
|
||||
private void updateMaxLinesByShrinkAnchor() {
|
||||
int lineCount = getLineCount();
|
||||
for (int line = 0; line < lineCount; line++) {
|
||||
@ -88,44 +88,44 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
if (mInitLayout && !mIsExpanded && getLineCount() > mMaxLines) {
|
||||
if (mInitLayout && !mIsExpanded && getLineCount() > mMaxLines && mMaxLines > 0) {
|
||||
mSnapshotText = findAndDeleteAnchor(getText());
|
||||
mInitLayout = false;
|
||||
showExpandButton();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setExpandText(String text) {
|
||||
this.mExpandText = text;
|
||||
}
|
||||
|
||||
|
||||
public void setExpandCallback(ExpandCallback callback) {
|
||||
this.mExpandCallback = callback;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setText(CharSequence text, BufferType type) {
|
||||
mInitLayout = true;
|
||||
super.setText(text, type);
|
||||
}
|
||||
|
||||
|
||||
private void showExpandButton() {
|
||||
String finalEndText = "";
|
||||
TextPaint paint = getPaint();
|
||||
|
||||
|
||||
Layout layout = getLayout();
|
||||
int start = layout.getLineStart(0);
|
||||
int lastLineEnd = layout.getLineEnd(mMaxLines - 1);
|
||||
int lastLineStart = layout.getLineStart(mMaxLines - 1);
|
||||
float lastLineRight = layout.getLineRight(mMaxLines - 1);
|
||||
|
||||
|
||||
int viewWidth = getWidth() - getPaddingRight() - getPaddingLeft();
|
||||
int additionalEndTextCount = 0;
|
||||
|
||||
|
||||
float expandTextWidth;
|
||||
if (mUseGradientAlphaEndText) {
|
||||
additionalEndTextCount = DEFAULT_ADDITIONAL_END_TEXT_COUNT;
|
||||
@ -133,15 +133,15 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
} else {
|
||||
expandTextWidth = paint.measureText(mExpandText);
|
||||
}
|
||||
|
||||
|
||||
CharSequence content = mSnapshotText.subSequence(start, lastLineEnd);
|
||||
|
||||
|
||||
if (viewWidth - lastLineRight > expandTextWidth) {
|
||||
if (mUseGradientAlphaEndText) {
|
||||
finalEndText = content.toString()
|
||||
.substring(content.length() - additionalEndTextCount, content.length()) + mEndText;
|
||||
finalEndText = finalEndText.replace("\n", "");
|
||||
|
||||
|
||||
content = content.subSequence(0, content.length() - additionalEndTextCount) + finalEndText + mExpandText;
|
||||
} else {
|
||||
content = content.toString().trim() + mExpandText;
|
||||
@ -154,10 +154,10 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
if (mUseGradientAlphaEndText) {
|
||||
subSequence = lastLineText.subSequence(0, i - additionalEndTextCount);
|
||||
subSequenceWidth = paint.measureText(subSequence.toString());
|
||||
|
||||
|
||||
finalEndText = lastLineText.subSequence(i - additionalEndTextCount, i) + mEndText;
|
||||
expandTextWidth = paint.measureText(finalEndText + mExpandText);
|
||||
|
||||
|
||||
if (viewWidth - subSequenceWidth > expandTextWidth) {
|
||||
finalEndText = finalEndText.replace("\n", "");
|
||||
content = mSnapshotText.subSequence(start, lastLineStart + i - additionalEndTextCount) + finalEndText + mExpandText;
|
||||
@ -166,7 +166,7 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
} else {
|
||||
subSequence = lastLineText.subSequence(0, i);
|
||||
subSequenceWidth = paint.measureText(subSequence.toString());
|
||||
|
||||
|
||||
if (viewWidth - subSequenceWidth > expandTextWidth) {
|
||||
content = mSnapshotText.subSequence(start, lastLineStart + i) + mExpandText;
|
||||
break;
|
||||
@ -174,18 +174,18 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SpannableStringBuilder msp = new SpannableStringBuilder(mSnapshotText);
|
||||
int length = msp.length();
|
||||
int startPosition;
|
||||
startPosition = content.length() - finalEndText.length() - mExpandText.length();
|
||||
startPosition = Math.max(startPosition, 0);
|
||||
|
||||
|
||||
// 避免越界
|
||||
if (startPosition >= length) return;
|
||||
|
||||
|
||||
msp.replace(startPosition, length, finalEndText + mExpandText);
|
||||
|
||||
|
||||
msp.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void updateDrawState(@NonNull TextPaint ds) {
|
||||
@ -193,24 +193,24 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
ds.setColor(ContextCompat.getColor(getContext(), R.color.theme_font));
|
||||
ds.setUnderlineText(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
mIsExpanded = true;
|
||||
setMaxLines(Integer.MAX_VALUE);
|
||||
setText(mSnapshotText);
|
||||
|
||||
|
||||
if (mExpandCallback != null) {
|
||||
mExpandCallback.onExpand();
|
||||
}
|
||||
}
|
||||
}, startPosition + mEndText.length(), msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
msp.setSpan(new GradientAlphaTextSpan(), startPosition, startPosition + finalEndText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
|
||||
setText(msp);
|
||||
setMovementMethod(CustomLinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取 maxLines + lineSpacingExtra + movementMethod 一起使用时产生的大小与 lineSpacingExtra 一样的底部空间
|
||||
*/
|
||||
@ -220,13 +220,13 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
int lastVisibleLineIndex = Math.min(getMaxLines(), getLineCount()) - 1;
|
||||
// 获取实际文字的最后一行的 index
|
||||
int lastActualLineIndex = getLineCount() - 1;
|
||||
|
||||
|
||||
if (lastVisibleLineIndex >= 0) {
|
||||
Layout layout = getLayout();
|
||||
int lastVisibleLineBaseline = getLineBounds(lastVisibleLineIndex, mLastVisibleLineRect);
|
||||
getLineBounds(lastActualLineIndex, mLastActualLineRect);
|
||||
int heightBetweenLastVisibleLineRectAndLastActualLineRect = (mLastActualLineRect.bottom - mLastVisibleLineRect.bottom);
|
||||
|
||||
|
||||
if (getMeasuredHeight() == getLayout().getHeight() - heightBetweenLastVisibleLineRectAndLastActualLineRect) {
|
||||
result = mLastVisibleLineRect.bottom - (lastVisibleLineBaseline + layout.getPaint()
|
||||
.getFontMetricsInt().descent + getPaddingBottom());
|
||||
@ -239,7 +239,7 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// 去掉锚点
|
||||
private CharSequence findAndDeleteAnchor(CharSequence charSequence) {
|
||||
int anchorIndex = charSequence.toString().indexOf(SHRINK_ANCHOR);
|
||||
@ -251,29 +251,29 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
return charSequence;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 此方法仅更改标记,不做实际展开的操作
|
||||
*/
|
||||
public void setIsExpanded(boolean isExpanded) {
|
||||
mIsExpanded = isExpanded;
|
||||
}
|
||||
|
||||
|
||||
public void setExpandMaxLines(int maxLines) {
|
||||
mMaxLines = maxLines;
|
||||
setMaxLines(maxLines);
|
||||
}
|
||||
|
||||
|
||||
public void setSelfCalculateMaxLinesCallback(SelfCalculateMaxLinesCallback callback) {
|
||||
mMaxLinesCalculatedCallback = callback;
|
||||
}
|
||||
|
||||
|
||||
public interface ExpandCallback {
|
||||
void onExpand();
|
||||
}
|
||||
|
||||
|
||||
public interface SelfCalculateMaxLinesCallback {
|
||||
void onMaxLinesCalculated(int maxLines);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user