Android 具有相同ID的视图在还原时获得相同属性

Android 具有相同ID的视图在还原时获得相同属性,android,Android,我有一个自定义组件,其中一个RadioGroup有两个RadioButton,id@+id/radioButton1和@+id/radioButton2。另一方面,有一个包含五个选项卡的TabActivity。在每个选项卡上,此组件被多次使用 问题是,当方向改变并且活动重新创建时,所有的RadioButton都加载了相同的属性,这包括android:text,android:margin,甚至是我创建的样式属性。所有具有相同ID的复选框也会发生这种情况 我花了一些时间试图发现为什么会发生这种情况

我有一个自定义组件,其中一个RadioGroup有两个RadioButton,id
@+id/radioButton1
@+id/radioButton2
。另一方面,有一个包含五个选项卡的TabActivity。在每个选项卡上,此组件被多次使用

问题是,当方向改变并且活动重新创建时,所有的RadioButton都加载了相同的属性,这包括
android:text
android:margin
,甚至是我创建的样式属性。所有具有相同ID的复选框也会发生这种情况

我花了一些时间试图发现为什么会发生这种情况,并得出结论,android正在onRestoreInstanceState中这样做。如果我对调用super方法的行进行注释,它可以正常工作

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    // super.onRestoreInstanceState(savedInstanceState);

}
应该是这样的吗?或者人们会怎么做才能导致这种情况


我猜这不是一种正常的行为,因为当创建自定义视图时,它会使用具有相同ID的相同视图来扩展相同的布局。因此,不可能每次实例化一个新的自定义视图为其子视图生成不同的ID。对我来说,在清单上使用上面的代码或android:configChanges似乎不是一个好办法。因此,非常感谢您的帮助。

您的savedInstanceState方法是什么样子的


我认为分配给radiobutton文本的变量不会在方向变化之间持续存在。请记住,当方向发生变化时,活动将完全重建/重新启动

经过一段时间的搜索,我终于找到了安卓谷歌群组中Romain Guy的一个很好的解释,尽管它没有提到自定义视图

“除了需要视图保存其状态时,可以使用相同的id。id为 当视图的状态被保存时,是什么标识视图的,以便工具箱 你认为你的两种观点是相同的,但在一段时间内确实如此 仅限活动。”

“在两个不同的活动中使用相同的id没有问题。以及 在相同的活动中使用相同的id没有问题,如果 你在做什么时很小心(例如,如果 在您的情况下, 因为活动是一组选项卡的一部分,所以它们实际上是 绑定到一个独特的上下文,这意味着您将在 共享ID。“


.

我不重写onSaveInstanceState方法。我只覆盖onRestoreInstanceState,以防止android重新加载具有相同属性集的相同id的视图。单选按钮文本正在接收上次出现的自定义视图的值,这就像android正在扫描整个布局,将视图状态与其id相关联(我猜是在savedInstanceState捆绑包中)然后为所有具有关联id的视图加载此状态。您是否尝试通过创建layout land文件夹并将相同的布局xml文件复制到其中来创建备用横向布局文件?Android会根据设备方向自动在两者之间切换。这可能会迫使设备使用“新”信息重建视图。另外一个想法是:你的应用程序所经历的需要持久性的状态是什么?将该对象作为变量、字符串或数组单独存储在共享首选项中可能是值得的。然后,应用程序可以根据存储的变量重新生成单选按钮的标签,而不是尝试在操作之间存储所有标签。我的应用程序有一个用户需要完成的大表单。此表单绑定到一个包含70多个字段的对象,因此它需要持久性,以防止用户在android进行配置更改时丢失数据。不只是链接到外部资源,您应该在此处包含一个(小的)相关部分-链接本身可能会腐烂,这不是一个好的答案。我也经历过这种情况。事实上,我花了几天的时间试图找到这个bug。最糟糕的是,在我的例子中,这些视图接收到一个错误的值,这会立即触发视图所代表的对象状态的变化,这意味着我正在破坏状态。我在一个SeekBar中看到了这种行为,该SeekBar嵌入到一个自定义视图中,该视图将SeekBar与一些其他组件分组。我在活动的各个地方重用了自定义视图,当然,能够重用XML文件是首选。