树中View对象的ID的唯一性

时间:2013-11-23 08:20:49

标签: android object view unique identifier

从Android开发人员documentation,声明如下:

  

ID在整个树中不一定是唯一的,但应该是   在您正在搜索的树的一部分中是唯一的(可能经常   是整棵树,所以最好是完全独特的   可能的)。

请帮助我理解,例如,“你要搜索的树的一部分”是什么意思?

示例,给出以下内容:

<AnOutterLayout>

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

  <ASuitableInnerLayout>

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

  </ASuitableInnerLayout>

</AnOutterLayout>

如果我有:

Button myButton = (Button) findViewById(R.id.my_button);

这里的搜索树是什么?

谢谢!

2 个答案:

答案 0 :(得分:0)

首先调用外层中的按钮。

这篇文章为您的问题提供了一个解释清楚的答案

Are Android View id supposed to be unique?

答案 1 :(得分:0)

“您正在搜索的树的一部分”通常是您正在调用findViewById的{​​{3}}的子项。

Activity中,findViewById方法就像这样实现(ViewGroup):

public View findViewById(int id) {
    return getWindow().findViewById(id);
}

好的,那么Window如何实施findViewByIdsource)?

public View findViewById(int id) {
    return getDecorView().findViewById(id);
}

getDecorView返回View - View的实现所做的全部返回(如果视图ID与传入的视图ID匹配)或null({{3} }):

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;
}

如果我们查看ViewGroupsource)的实现,那会更有趣:

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;
}

所以你看到ViewGroup遍历其子项搜索你传入的ID。我不确定mChildren的顺序,但我怀疑它会按你添加的顺序排列层次结构的视图(仅检查 - addView(View child)确实会将视图添加到mChildren列表的末尾,而addView(View child, int index)会在列表中的index位置添加视图

因此,对于您的示例,返回的按钮取决于您ViewGroup上调用的findViewById

如果您拨打anOutterLayout.findViewById(R.id.my_button),则会获得第一个按钮 - 因为这是第一个包含该ID的子元素。

如果您拨打anInnerLayout.findViewById(R.id.my_button),则会收到第二个按钮。

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

<AnOutterLayout>

  <ASuitableInnerLayout>

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

  </ASuitableInnerLayout>

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

</AnOutterLayout>

然后anOutterLayout.findViewById(R.id.my_button)实际上会返回内部布局中的按钮 - 因为此视图之前已添加到层次结构中,因此在该视图的子级列表中较早。 / p>

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