android开发者指南指出,你的activity中的Views
需要有唯一的id才能在onRestoreInstanceState()
中恢复,这是因为onRestoreInstanceState()
是通过创建一个以id为键的SparseArray
来工作的。
我觉得这非常奇怪,因为很多标准的Android方法都鼓励重用id。例如,ArrayAdapter
的所有构造函数都将resourceId作为参数,因此ListView
中的所有子元素都会膨胀相同的xml资源。类似地,如果您在xml中使用<include layout ...>
,则会重用视图id。
因此,除非开发人员实际上没有使用标准的、推荐的方法,否则我看不出有多少应用程序实际上满足了所有Views
都有唯一id的要求。
这个结论是错误的吗?还有,如果id不是都不同,onRestoreInstanceState
的行为是什么,这种行为是可以接受的吗?
- 编辑**
相关引文见http://developer.android.com/training/basics/activity-lifecycle/recreating.html页,内容如下:
注意:为了让Android系统恢复Activity中视图的状态,每个视图必须具有唯一ID,该ID由android:id属性提供。
注意:始终调用onRestoreInstanceState()的超类实现,以便默认实现可以恢复视图层次结构的状态。
2条答案
按热度按时间ymdaylpp1#
AdapterView
(用于利用Adapter
的所有ViewGroup
的基类)被实现为不保存或恢复其子View
的状态,因为这是Adapter
的域并且应当在该级别处理。对于静态包含在多个点的子布局,如果它有任何要保存的状态,则需要为所有有状态的
View
分配唯一的id,或者从Activity
或Fragment
手动管理状态。不幸的是,id需要在整个
View
结构中是唯一的,而不仅仅是在它的兄弟之间,这是由于整个结构的状态保存在一个一维SpareArray
中,因此如果在结构中有多个有状态View
共享相同的id,则仅保存结构中最后一个的状态。并且在状态恢复时它将被应用于具有该ID的所有ViewGroup
。gzszwxb42#
一个简单的解决方案是通过编程方式分配ID。
假设您膨胀了一些视图
MyCustomView
,其中包含一些名为nameEditText的EditText
。在创建视图时,您可能会有以下内容:这样,保存状态将根据给定的id存储值,状态的恢复将在视图创建后发生。
您可以为此目的在资源文件上创建您的id: