从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);
这里的搜索树是什么?
谢谢!
答案 0 :(得分:0)
答案 1 :(得分:0)
“您正在搜索的树的一部分”通常是您正在调用findViewById
的{{3}}的子项。
在Activity
中,findViewById
方法就像这样实现(ViewGroup
):
public View findViewById(int id) {
return getWindow().findViewById(id);
}
好的,那么Window
如何实施findViewById
(source)?
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;
}
如果我们查看ViewGroup
(source)的实现,那会更有趣:
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>
然后 这假定视图按照它们在XML视图层次结构中的显示顺序添加。 anOutterLayout.findViewById(R.id.my_button)
实际上会返回内部布局中的按钮 - 因为此视图之前已添加到层次结构中,因此在该视图的子级列表中较早。 / p>