Android 树中视图对象ID的唯一性

Android 树中视图对象ID的唯一性,android,object,view,unique,identifier,Android,Object,View,Unique,Identifier,安卓开发者的声明如下: ID不必在整个树中都是唯一的,但应该是唯一的 在您正在搜索的树的部分中是唯一的(通常 是整棵树,所以最好在 可能的) 请用一个例子帮助我理解“你正在搜索的树的一部分”是什么意思 举例如下: <AnOutterLayout> <Button android:id="@+id/my_button".../> <ASuitableInnerLayout> <Button android:id="@+id/my_bu

安卓开发者的声明如下:

ID不必在整个树中都是唯一的,但应该是唯一的 在您正在搜索的树的部分中是唯一的(通常 是整棵树,所以最好在 可能的)

请用一个例子帮助我理解“你正在搜索的树的一部分”是什么意思

举例如下:

<AnOutterLayout>

  <Button android:id="@+id/my_button".../>

  <ASuitableInnerLayout>

    <Button android:id="@+id/my_button".../>

  </ASuitableInnerLayout>

</AnOutterLayout>
这里的搜索树是什么


谢谢

将首先调用外层中的按钮

这篇文章对你的问题有很好的解释

“您正在搜索的树的一部分”通常是您在上调用的
findViewById
的子树

活动
中,
findViewById
方法的实现方式如下():

好的,那么
窗口如何实现
findViewById
()

getDecorView
返回一个
视图
——而
视图
的实现只返回自身(如果视图ID与传入的视图ID匹配),或null():

因此,您会看到一个
ViewGroup
遍历它的子对象,搜索您传入的ID。我不确定
mChildren
的顺序,但我怀疑它会按照您将视图添加到层次结构的顺序(刚刚选中-
addView(View child)
会将视图添加到
mChildren
列表的末尾,其中as
addView(View child,int index)
会在列表中的
index
位置添加视图)

因此,对于您的示例,返回哪个按钮将取决于您调用的是哪个
findViewById

如果调用
anouttrayout.findViewById(R.id.my_button)
,将得到第一个按钮,因为这是它遇到的第一个包含该id的子元素

如果调用
aninerLayout.findViewById(R.id.my_按钮)
,则会得到第二个按钮

但是,如果布局文件如下所示:

<AnOutterLayout>

  <ASuitableInnerLayout>

    <Button android:id="@+id/my_button".../>

  </ASuitableInnerLayout>

  <Button android:id="@+id/my_button".../>

</AnOutterLayout>

然后
anOutterLayout.findViewById(R.id.my_按钮)
将实际返回内部布局中的按钮-因为此视图先前添加到层次结构中,因此在该视图的子视图列表中较早


这假设视图是按照它们在XML视图层次结构中的显示顺序添加的。

如果在同一布局中有相同id的视图,Lint将发出警告,这是一个好的指针。但是,我想特别地理解“……部分……”,因为文件明确指出了这一点。否则,很明显,选择了第一个匹配项。但是,当文档提到可以在树的一部分中搜索时,就会出现混淆。所以,我想知道如何在子树中搜索?换句话说,如何告诉Android在子树中搜索?这是一个有趣的想法,我从来没有想过。到目前为止,我没有看到任何关于这个话题的讨论。Android会为你做这件事,而且似乎它不允许定制搜索。
public View findViewById(int id) {
    return getWindow().findViewById(id);
}
public View findViewById(int id) {
    return getDecorView().findViewById(id);
}
public final View findViewById(int id) {
    if (id < 0) {
        return null;
    }
    return findViewTraversal(id);
}

protected View findViewTraversal(int id) {
    if (id == mID) {
        return this;
    }
    return null;
}
protected View findViewTraversal(int id) {
    if (id == mID) {
        return this;
    }

    final View[] where = mChildren;
    final int len = mChildrenCount;

    for (int i = 0; i < len; i++) {
        View v = where[i];

        if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
            v = v.findViewById(id);

            if (v != null) {
                return v;
            }
        }
    }

    return null;
}
<AnOutterLayout>

  <ASuitableInnerLayout>

    <Button android:id="@+id/my_button".../>

  </ASuitableInnerLayout>

  <Button android:id="@+id/my_button".../>

</AnOutterLayout>