【问题标题】:Are Android View id supposed to be unique?Android View id 应该是唯一的吗?
【发布时间】:2013-08-05 20:47:04
【问题描述】:

好吧,我很困惑的是 Android id 是否需要是唯一的。这就是产生混淆的原因:
假设有一个Activity 有一个TextView (android:id="text") 和一个Button (android:id="button")。 Button 将文本视图的文本设置为随机文本。因此,要添加监听器,我将检索 按钮为
Button b = (Button) findViewById(R.id.button),然后添加监听器来完成任务。
现在,我可以从DialogFragmentFragment 和具有相同 ID 的 R.id.text 引用这个 same TextView,毫无疑问,所有更改都将应用于此文本视图.

在子类化BaseAdapter 的情况下,您需要覆盖getView,如果有必要,您可以在其中进行膨胀,如果没有,则进行更改。现在,您以几乎相同的方式检索Views。差不多。
你做一个convertView.findViewById(..)

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

我的理解是,在夸大它们的视图的上下文中,id 是独一无二的。由于我是初学者,我要求澄清

艾哈迈德回答后更新

所以,这意味着我不能使用相同的布局在Activity 中膨胀两个Fragment。这将导致异常。两者都被同一个Activity 膨胀,因此属于同一个实例。 id会冲突

【问题讨论】:

  • 不会抛出异常。对于 Android 来说,检查是否有冲突的 id 太昂贵了。唯一的问题是,如果您使用 findViewById() 搜索视图,您可能会收到带有该 ID 的 any 视图。因此,只要 id 在您正在搜索的视图的子树中是唯一的,就可以了。
  • @AlexMDC 是的,完全正确。你澄清了。如果 id 相同,我会取回任何视图。 :)
  • “id 在膨胀它们的视图的上下文中是唯一的”。你的意思是,如果你想避免 ID 冲突,它们在被调用 findViewById() 方法的 Activity 或 View 的上下文中应该是唯一的?

标签: android


【解决方案1】:

documentation你可以阅读

ID 不必在整个树中是唯一的但它应该是在您正在搜索的树的一部分(通常可能是整棵树)中是唯一的,因此最好尽可能完全独一无二)。

这意味着如果您对所有视图使用相同的 id,则不会有例外,但显然布局将变得无用。

FindViewById 的工作原理是遍历一棵树,直到找到具有搜索到的 id 的第一个元素并返回它(如果没有找到,则返回 null)。如果您在树中有几个具有相同 id 的元素,您将始终获得相同的元素,即树中的第一个元素。

您可能有大量使用相同布局充气的片段,就像您拥有每个元素都具有相同布局的 ListView 一样,这是因为充气程序不关心 id 值。 它只是读取 XML 文件并创建具有正确视图对象的树而已。

【讨论】:

    【解决方案2】:

    您为什么使用android:id="text"?您应该使用android:id="@+id/text"android:id="@id/text",具体取决于您选择的方式。此外,getView 相对于滚动或不滚动的项目位置ListView

    【讨论】:

    • 是的,我的错。对不起:)
    • 是的,id 在特定区域是唯一的,即。在ListView 项目中,当您为TextView 膨胀行ID 时,与ImageView 的ID 不同。但是对于TextViewImageView 的每一行ID 都是相同的。
    • 他们是不同的视图:)
    • 我试图尽可能简单地展示它;)当您使用 @+id/ 时,将收集 id 并根据您所引用的项目使用简单的 R.id.text 系统选择你想要的这个
    • ID中"@+id/"的意义是什么?你能链接到文档吗?
    【解决方案3】:

    你做一个 convertView.findViewById(..)。

    如果所有视图都需要有一个唯一的 id,如何更改 getView 中的 View 内容不会导致杂乱无章的行为?

    这是因为您通过膨胀来创建视图的实例。在这种情况下,ID 必须是唯一的。否则你可能会得到一个ClassCastException(如果两个不同类型的视图共享相同的 ID)。

    不可能维护ListView,其中每一行都必须为其所有视图具有唯一标识符。

    所以,这意味着我不能在一个 Activity 中为两个 Fragment 充气 通过使用相同的布局。这将导致异常。两者都是 由同一个 Activity 膨胀,因此属于同一个实例。这 ids会冲突

    不,片段以不同的方式工作。您必须在片段onCreateView() 方法中返回一个膨胀的视图。所以每个片段都必须膨胀视图,这会导致有 2 个单独的视图对象。

    【讨论】:

    • 所以,我的理解是对的。每个膨胀的View 都有自己的一组 id :)
    • 是的,ID 集是相同的,只是每个视图的不同实例可以修改视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 2011-04-04
    相关资源
    最近更新 更多