android中TextView带有链接的文本在点击时会导致宽度变大的问题排查记录
- 最近发现了一个问题,就是TextView里的链接在点击后宽度会变大一点,重新setText后又会变回去,但是并不会所有带有链接的文本都会出现这种情况
- 跟踪时发现TextView的onMeasure会走入不同的条件,进而产生不同的宽度
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
...
if (mLayout != null && mEllipsize == null) {
des = desired(mLayout);
}
...
if (boring == null || boring == UNKNOWN_BORING) {
if (des < 0) {
des = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mTransformed, 0,
mTransformed.length(), mTextPaint, mTextDir, widthLimit));
}
width = des;
} else {
width = boring.width;
}
...
}
- 上面代码注释的地方就是两个关键点,因为这里计算出来的des是不同的,导致画面上会有宽度变大的情况出现
- 再仔细跟踪desired和Layout.getDesiredWidthWithLimit方法,发现desired里在计算宽度时会把行末的换行符宽度计算进去,而Layout.getDesiredWidthWithLimit则不会,因此才会出现在点击链接时宽度变大了一点,而这一点就是行末换行符的宽度
- 但即使知道了这一点,还是想不出如何解决这个问题,但是原生的TextView在有链接并且行末是换行符时并不会有宽度变化这种情况,因此敢肯定是自己在继承TextView做了某些改动而导致的
- 最后千辛万苦终于发现Selection.setSelection这个方法导致的,原来是在继承LinkMovementMethod的onTouchEvent中调用了Selection.setSelection这个方法,只要我将这个方法注释,就不会再出现宽度发生变化的情况了
- 主要是Selection.setSelection会触发重新测量的流程,而此时计算得到的宽度就会是带有换行符的宽度
- 因此解决方案就是不要在onTouchEvent中调用Selection.setSelection
- 但是这个样子还是无法释怀,直到看到这篇文章有换行时切换软键盘,TextView宽度抖动问题 - 简书,才恍然大悟,还可以这么解决,TextView.setEllipsize果然是较简单的解决办法
参考