java - 为什么屏幕旋转后setSpan不起作用?

标签 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 秒间隔后将每个字母着色为蓝色。

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

最佳答案

它发生了,因为旋转后 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 的回调。

关于java - 为什么屏幕旋转后setSpan不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47624340/

相关文章:

java - viewpager2 降低水平滚动的灵敏度

Java自定义组件像素颜色

java - 启动 Activity android 时聚焦 ListView 中的第一项

node.js - Promise 和 Azure 语音转文本

jQuery:按顺序加载脚本

java - 检查java字符串中的^字符

java - log4j 与 oracle 给出异常 - 无效的 sql 语句

android - 在 android 应用程序上进行 OTP 验证后,fabric digits 返回一个空的 phoneNumber 对象

java - 尝试向 React Native 添加 openFile 方法,无法调用 getCurrentActivity

c# - 当您必须同时拥有异步和同步版本的代码时,如何避免违反 DRY 原则?