![](/img/trans.png)
[英]OnRestoreInstanceState() not applied on View IDs that have been set programmatically
[英]onRestoreInstanceState() and Unique View Ids
android 开发人员指南说,您活动中的Views
需要具有唯一 ID,以便在onRestoreInstanceState()
中恢复它们。 这是因为onRestoreInstanceState()
通过创建一个以 id 作为键的SparseArray
来工作。
我觉得这非常奇怪,因为许多标准 Android 方法都鼓励重复使用 ID。 例如, ArrayAdapter
的所有构造函数都将 resourceId 作为参数,因此相同的 xml 资源会为ListView
中的所有子项扩充。 同样,如果您在 xml 中使用<include layout...>
,您就是在重复使用视图 ID。
因此,除非开发人员实际上没有使用标准的、推荐的方法,否则我看不到有很多应用程序实际上满足所有Views
都具有唯一 ID 的要求。
这个结论错了吗? 另外,如果 id 不完全不同, onRestoreInstanceState
的行为是什么,这种行为是否可以接受?
编辑
相关引述出现在http://developer.android.com/training/basics/activity-lifecycle/recreating.html页面,内容如下:
注意:为了让 Android 系统恢复您活动中视图的 state,每个视图必须有一个唯一的 ID,由 android:id 属性提供。
注意:始终调用 onRestoreInstanceState() 的超类实现,以便默认实现可以恢复视图层次结构的 state。
AdapterView
(所有使用Adapter
ViewGroup
的基类),以便不保存或还原其子View
的状态,因为这是Adapter
的域,应在该级别上进行处理。
对于在多个点静态包含的子布局,如果要保存任何状态,则需要为所有有状态View
分配唯一的ID,或者从Activity
或Fragment
手动管理状态。
不幸的是,id在整个View
结构中必须是唯一的,而不仅仅是它们之间的同级。 这是由于以下事实:整个结构的状态保存在一个一维SpareArray
。 因此,如果结构中有多个共享相同ID的有状态View
,则仅保存结构中最后一个状态的状态,并将在状态恢复时将其应用于具有该ID的所有View
。
一种简单的解决方案是以编程方式分配ID 。
ID不是一成不变的,因此您可以在视图创建期间更改 ID。
假设您膨胀了一些视图MyCustomView
,其中有一些名为 nameEditText 的EditText
。 在创建视图时,您可以拥有以下内容:
binding.view1.nameEditText.id = R.id.pageX_field1
binding.view2.nameEditText.id = R.id.pageX_field2
这样 save state 将根据给定的 ID 存储值。 state 的恢复将在创建视图后发生。
为此,您可以在资源文件中创建您的 ID:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- PAGE X IDS -->
<item type="id" name="pageX_field1" />
<item type="id" name="pageX_field2" />
</resources>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.