我对我的代码中看似错误的内容进行了最小程度的重现。创建一个空应用程序并将以下内容粘贴到:
<!-- 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/