为什么设置跨度在屏幕旋转后不起作用?



我对我的代码中似乎是一个错误进行了最小的复制。创建一个空的应用程序并粘贴以下内容:

<!-- content_main.xml -->
<EditText
    android:id="@+id/main_editText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
// MainActivity.java
private static SpannableStringBuilder sText;
private EditText mEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (sText == null) {
        sText = new SpannableStringBuilder("Hello world!");
    }
    mEditText = (EditText) findViewById(R.id.main_editText);
    mEditText.setEditableFactory(new Editable.Factory() {
        @Override
        public Editable newEditable(CharSequence source) {
            return (Editable) source;
        }
    });
    mEditText.setText(sText, TextView.BufferType.EDITABLE);
    workLoop(0);
}
private void workLoop(final int index) {
    SpannableStringBuilder text = sText;
    if (index == text.length()) {
        return;
    }
    text.setSpan(new ForegroundColorSpan(Color.BLUE), index, index + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    Handler uiThreadHandler = new Handler(Looper.getMainLooper());
    uiThreadHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            workLoop(index + 1);
        }
    }, 5000);
}

说明:此代码将文本Hello, world!放在性能下文中,然后在5秒钟的间隔后继续为每个字母蓝色。

但是,如果我旋转屏幕,导致活动被破坏/重新创建,则文本会停止着色。为什么会发生?

发生了,因为旋转后Activity调用onRestoreInstanceState()回调方法并覆盖EditText的值。您应该添加类似的东西:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    mEditText.setText(sText, TextView.BufferType.EDITABLE);
}

也在这方面注意:

uiThreadHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        workLoop(index + 1);
    }
}, 5000);

匿名Runnable停留在屏幕旋转而创建的MainActivity新实例之后,对旧MainActivity实例进行了参考。我建议在Activity.onDestroy()方法中清除Handler的回调。

最新更新