android onRestoreInstanceState()和唯一视图ID

webghufk  于 2023-01-15  发布在  Android
关注(0)|答案(2)|浏览(130)

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()的超类实现,以便默认实现可以恢复视图层次结构的状态。

ymdaylpp

ymdaylpp1#

AdapterView(用于利用Adapter的所有ViewGroup的基类)被实现为不保存或恢复其子View的状态,因为这是Adapter的域并且应当在该级别处理。
对于静态包含在多个点的子布局,如果它有任何要保存的状态,则需要为所有有状态的View分配唯一的id,或者从ActivityFragment手动管理状态。
不幸的是,id需要在整个View结构中是唯一的,而不仅仅是在它的兄弟之间,这是由于整个结构的状态保存在一个一维SpareArray中,因此如果在结构中有多个有状态View共享相同的id,则仅保存结构中最后一个的状态。并且在状态恢复时它将被应用于具有该ID的所有ViewGroup

gzszwxb4

gzszwxb42#

一个简单的解决方案是通过编程方式分配ID

    • Id**不是不可变的,因此您可以在创建视图期间更改Id。

假设您膨胀了一些视图MyCustomView,其中包含一些名为nameEditText的EditText。在创建视图时,您可能会有以下内容:

binding.view1.nameEditText.id = R.id.pageX_field1
binding.view2.nameEditText.id = R.id.pageX_field2

这样,保存状态将根据给定的id存储值,状态的恢复将在视图创建后发生。
您可以为此目的在资源文件上创建您的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>

相关问题