设置width尽量不要使用wrap_content
调用setText时,会检查是否需要重新布局:
private void setText(CharSequence text, BufferType type,boolean notifyBefore, int oldlen) {
...
if (mLayout != null) {
checkForRelayout();
}
...
}
在检查时,如果width设置为WRAP_CONTENT,必然会导致整个视图树重新布局:
private void checkForRelayout() {
if ((mLayoutParams.width != LayoutParams.WRAP_CONTENT
|| (mMaxWidthMode == mMinWidthMode && mMaxWidth == mMinWidth))
&& (mHint == null || mHintLayout != null)
&& (mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight() > 0)) {
...
requestLayout();
invalidate();
} else {
...
requestLayout();
invalidate();
}
}
width设置为WRAP_CONTENT,调用setText方法后的整体执行流程是这样的,measure、layout、draw全部都执行了:
width设置为MATCH_CONTENT或者指定了尺寸,调用setText方法后的整体执行流程简化了很多,只有draw执行了:
解决办法
使用macth_content
在不影响视觉效果的情况下,使用macth_content可以规避重新布局
父布局使用ConstraintLayout
macth_content适用的条件非常苛刻,除了macth_content和warp_content,就是指定width,但是指定width不利于ui适配。
在LinearLayout父布局中可以设置width = 0,通过给TextView设置weight规避重新布局。
更好的办法是父布局使用ConstraintLayout,在ConstraintLayout,TextView的width = 0,并不会影响TextView内容的展示。