Android视图ID应该是唯一的吗?

28

好的,我现在感到困惑的是Android ID是否需要唯一。这就是为什么会出现混淆的原因:
假设有一个Activity拥有一个TextView(android:id="text")和一个Button(android:id="button")。当Button被点击时,它会将TextView的文本设置为随机文本,因此要添加监听器,我将检索按钮并执行任务:
Button b = (Button) findViewById(R.id.button) 然后添加监听器进行操作。
现在,我可以用相同的ID R.id.textDialogFragmentFragment等地方引用这个相同TextView,所有更改都会被应用于这个文本视图,没有疑问。

在子类化BaseAdapter的情况下,您需要覆盖getView,如果需要则进行膨胀,否则进行更改。现在,您使用几乎相同的方式检索Views
您可以使用convertView.findViewById(..)

如果所有视图都需要具有唯一的ID,那么在getView中更改View的内容不会导致混乱吗?
我的意思是,所有膨胀的视图都具有与布局中定义的相同的ID。

我的理解是,这些ID在膨胀它们的视图的上下文中是唯一的。由于我是一个初学者,所以我想要澄清

Ahmad回答后更新

因此,这意味着我不能使用相同的布局在一个Activity中膨胀两个Fragment。这将导致异常。由同一个Activity膨胀,因此属于同一个实例,ID将发生冲突。


1
不会抛出异常。对于Android来说,检查是否存在冲突的id太过昂贵。唯一的问题是,如果你使用findViewById()搜索视图,你可能会收到具有该id的任何视图。只要在你搜索的视图子树中id是唯一的,就不会有问题。 - Alex MDC
@AlexMDC 是的,没错。你解释得很清楚。如果 ID 相同,我将返回任何视图。 :) - An SO User
“ids在填充它们的视图上下文中是唯一的。”您的意思是,如果要避免ID冲突,它们应该在调用findViewById()方法的Activity或View的上下文中是唯一的吗? - LarsH
3个回答

34
文档中,您可能会读到:

标识符在整个树中不需要是唯一的,但在搜索的树部分中必须是唯一的(这通常可能是整个树,因此最好尽可能完全唯一)。

这意味着,如果您为所有视图使用相同的ID,则不会出现异常,但布局显然会变得无用。
FindViewById 的工作原理很简单,它通过遍历树直到找到具有搜索 ID 的第一个元素并返回它(如果没有找到则返回null)。 如果在树中有几个具有相同 ID 的元素,则始终会获取同一元素,即树中第一个元素。
您可能会用相同的布局充气许多片段,就像您拥有ListView,其中每个元素都具有相同的布局,这是因为填充器不关心ID值。 它只是读取XML文件并创建带有正确视图对象的树而已。

2
你需要使用convertView.findViewById(..)方法获取视图。在此实例中,ID需要是唯一的,否则可能会出现ClassCastException异常(如果两种不同类型的视图共享相同的ID)。但是,对于ListView来说,要求每个行视图都具有唯一标识符是不可能的。
至于你提到的在Activity中使用相同布局来充气两个Fragment的问题,这并不会导致异常。因为Fragment的工作方式不同,你必须在Fragment的onCreateView()方法中返回一个充气后的视图。因此,每个Fragment都必须充气视图,这将导致有2个独立的视图对象。

2
所以,我的理解是正确的。每个充气的“View”都有自己的ID集 :) - An SO User
是的,有点像,ID集合是相同的,只是您拥有修改视图的不同实例。 - Ahmad

2

你为什么要使用 android:id="text" 呢?你应该根据你选择的方式使用 android:id="@+id/text" 或者 android:id="@id/text"。另外,getView 是相对于滚动或未滚动的 ListView 上的项目位置的。


是的,那是我的错。抱歉 :) - An SO User
是的,在特定区域中id是唯一的,例如在填充行时,TextView的id与ImageView的id不同。但是对于每一行来说,TextViewImageView的id是相同的。 - be4code
它们是不同的视图 :) - An SO User
我尽可能简单地展示了它 ;) 当您使用@+id/时,这些 ID 将被收集,并根据您使用的项目来引用该项,仅需使用 R.id.text,系统就会选择您想要的那个。 - be4code
"@+id/"在ID中的意义是什么?您能提供文档链接吗? - dinosaur
我认为这里有很好的解释链接 - be4code

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接