为什么屏幕旋转后setSpan没有工作?

时间:2017-12-03 23:09:03

标签: java android asynchronous android-activity

我对代码中的错误进行了最小化的重复。创建一个空应用并粘贴以下内容:

<!-- 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!放入EditText中,然后在每隔5秒后将每个字母的颜色设置为蓝色。

但是,如果我旋转屏幕,导致活动被销毁/重新创建,文本将停止变色。为什么会这样?

1 个答案:

答案 0 :(得分:1)

会发生这种情况,因为轮换后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实例。我建议在Handler方法中清除Activity.onDestroy()的回调。