携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的19天,点击查看活动详情
临界点
在A屏,使用setText,在EditText2和TextView3的字段中输入值,
去到B屏,出现了又回到A屏的情况。
此时EditText中输入的值保持不变,而TextView中输入的值却全部消失了。
调试
因为输入到每个视图的值都不同,所以做了两个假设。
- TextView对应的数据打不进来。
- 再次只有 onViewCreated setText 中与 EditText 相关的值。
两者测试结果,所有数据都正常进来,没有setText问题。
寻找值的差异,EditText 和 TextView 之间存在差异。
结论
恢复View内部状态时,TextView的文本被初始化,但EditText的文本保持不变。
那么两者有什么区别呢?
调试
-
setText 的实现区别??
- 结论是没有区别。
EditText不会覆盖setText() 并按 原样使用TextView 的 setText() 。
- 结论是没有区别。
-
onSaveInstanceState() 中是否有一部分根据 View 属性以不同的方式保存和恢复状态?
@Override
public void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
} SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
// XXX 也恢复缓冲区类型,以及许多其他的东西
if (ss.text != null) {
setText(ss.text);
}
.....
SavedState 如果您查看上面的 实现,您 text 正在导入和 setText()调用 .
如果是这样 TextView,''的文本是否也应该恢复?
但是 既然没有 恢复, TextView 也就 意味着它没有把状态保存在 .text``text==null``onSaveInstanceState()
TextView 为了找到没有保存状态的原因, onSaveInstanceState() 让我们看一下实现。
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState(); // 如果我们被迫保存状态
final boolean freezesText = getFreezesText();
boolean hasSelection = false;
int start = -1;
int end = -1;
if (mText != null) {
start = getSelectionStart();
end = getSelectionEnd();
if (start >= 0 || end >= 0) {
// 或者如果有选择则保存状态
hasSelection = true;
}
}
if (freezesText || hasSelection) {
SavedState ss = new SavedState(superState);
if (freezesText) {
if (mText instanceof Spanned) {
final Spannable sp = new SpannableStringBuilder(mText);
if (mEditor != null) {
removeMisspelledSpans(sp);
sp.removeSpan(mEditor.mSuggestionRangeSpan);
}
ss.text = sp;
} else {
ss.text = mText.toString();
}
}
SavedStateof text 正在 getFreezesText() == true分配 if 。
API 文档 getFreezesText() 中的描述如下。
返回此文本视图是否将其全部文本内容包含在冻结的冰柱中。对于 EditText,它总是返回 true。
此外 freezesText ,属性的描述如下。
如果设置,文本视图将在其冻结的冰柱内包括其当前的完整文本,以及诸如当前光标位置之类的元数据。默认情况下这是禁用的;当文本视图的内容未存储在诸如内容提供者之类的持久位置时,它会很有用。对于 EditText,无论属性的值如何,它始终处于启用状态。
定论
EditText 的 greezesText 属性始终为 true .
@Override
public boolean getFreezesText() {
return true;
}
毕竟, EditText被 覆盖getFreezesText()总是 true return 。
因此,与 TextView 不同,可以保留文本状态。 如果 将
TextView 属性 设置 为 ,则 可以保留文本状态。setFreezesText(Boolean)``freezesText``true