如何让HTextView(com.hanks.htextview.HTextView)支持多行缩放文本效果?
解决HTextView多行文本崩溃的问题
我之前也踩过这个控件的多行兼容坑,本质是不管是原hanks版本还是yikwing的fork版HTextView,核心实现都是基于单行文本设计的——不管是控件的测量逻辑,还是字符动画的坐标计算,都默认只处理单行场景,传入多行文本时就会因为预期外的字符位置、测量值触发崩溃。
下面是亲测有效的修复步骤:
1. 先修正HTextView的基础属性与测量逻辑
首先要让控件本身支持多行显示,修改HTextView类的代码:
- 在构造方法里新增两行,关闭单行限制:
public HTextView(Context context, AttributeSet attrs) { super(context, attrs); // 新增这两行,解除单行强制限制 setSingleLine(false); setHorizontallyScrolling(false); } - 重写
onMeasure方法,确保控件能正确计算多行文本的高度:@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 先调用TextView默认测量逻辑,它会自动处理多行文本的高度计算 super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 若有自定义需求,可在这里调整最终测量的宽高 int measuredWidth = getMeasuredWidth(); int measuredHeight = getMeasuredHeight(); setMeasuredDimension(measuredWidth, measuredHeight); }
2. 修复动画逻辑的多行适配
这是解决崩溃的核心——原动画类(比如ScaleText、RainbowText这类实现Animation接口的类)在计算字符位置时,默认只取单行的Y坐标,多行时会导致坐标错误甚至数组越界。
以ScaleText为例,修改它的prepareAnimation方法,正确获取每个字符所在行的坐标:
@Override public void prepareAnimation(HTextView hTextView) { Layout layout = hTextView.getLayout(); if (layout == null) return; char[] text = hTextView.getText().toString().toCharArray(); int lineCount = layout.getLineCount(); mCharAnimators = new ArrayList<>(); // 遍历每一行文本 for (int i = 0; i < lineCount; i++) { int lineStart = layout.getLineStart(i); int lineEnd = layout.getLineEnd(i); // 遍历当前行的每个字符 for (int j = lineStart; j < lineEnd; j++) { float charX = layout.getPrimaryHorizontal(j); float charY = layout.getLineBaseline(i); // 保留原动画逻辑,仅替换为当前行的字符坐标 Animator animator = createCharAnimator(charX, charY, text[j]); mCharAnimators.add(animator); } } }
其他动画类(如FallText、RippleText等)也要做类似修改,确保遍历所有行的字符,并使用对应行的Y坐标计算动画位置。
3. 布局里的配套设置
在XML布局中给HTextView添加多行相关属性,和代码设置保持一致:
<com.hanks.htextview.HTextView android:id="@+id/htext" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="start|top" android:inputType="textMultiLine" android:singleLine="false" android:textSize="16sp" />
如果你的崩溃Logcat有特定异常信息(比如IndexOutOfBoundsException或NullPointerException),可以把具体内容贴出来,我能帮你更精准地定位问题。
内容的提问来源于stack exchange,提问作者Cap. MH
相关产品推荐
相关产品推荐

