【Android开发】TextView中getText()方法踩坑指南

本文约 900 字,阅读需 2 分钟。

【Android开发】TextView中getText()方法踩坑指南

本文记录了在使用TextViewgetText()方法时,由于编码不规范导致的诡异问题。

问题背景

大意可以描述为以下一段代码:

public class MainActivity extends Activity {
    public static final String label = "中文";
    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            TextView textView = findViewById(R.id.tv_text);
            textView.setText(label);
            if (label.equals(textView.getText())) {
                // 低版本判断为false,高版本判断为false
            }
        }
}

问题排查

经过debug之后,发现textView.getText()返回的类型是android.text.SpannableString,但是在高版本机器上返回为android.text.String。为此,我们阅读了TextView的源码,发现有两处执行了setText(mText, BufferType.SPANNABLE);这个方法,其中一处是在getIterableTextForAccessibility方法中:

/**
 * @hide
 */
@Override
public CharSequence getIterableTextForAccessibility() {
    if (!(mText instanceof Spannable)) {
        setText(mText, BufferType.SPANNABLE);
    }
    return mText;
}

正好我们的工程就要求开启辅助功能,上面的代码是Android4.4中TextView的实现,而在Android6.0中,该方法的实现为:

/**
 * @hide
 */
@Override
public CharSequence getIterableTextForAccessibility() {
    return mText;
}

看来因为辅助功能的开启触发了这个方法,导致了equals()方法在不同版本上表现不一致。 此外setSelectAllOnFocus方法也可能会导致setText(mText, BufferType.SPANNABLE);的执行:

/**
 * Set the TextView so that when it takes focus, all the text is
 * selected.
 *
 * @attr ref android.R.styleable#TextView_selectAllOnFocus
 */
@android.view.RemotableViewMethod
public void setSelectAllOnFocus(boolean selectAllOnFocus) {
    createEditorIfNeeded();
    mEditor.mSelectAllOnFocus = selectAllOnFocus;

    if (selectAllOnFocus && !(mText instanceof Spannable)) {
        setText(mText, BufferType.SPANNABLE);
    }
}

因此,如果TextView设置了android:selectAllOnFocus="true"属性,也会导致类似的问题。

总结

getText()方法其实是返回一个CharSequence,对应不同的实现(如StringSpannableString),建议写法为:

if (textView.getText() != null) {
    if (label.equals(textView.getText().toString())) {
                
    }
}

类型统一之后就不会出现此类“诡异”问题了,也说明了编码习惯的重要性!!

感谢应用宝终端技术团队同学的分享。

总阅读量次。