脚本宝典收集整理的这篇文章主要介绍了View.findViewById是深度优先的,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
我喜欢用简单的单词来给XMl中的元素加id,比如一个View里面要展示一行文字和一个图标,那么,展示文字的就叫text,展示图标的就叫icon
像这样:
<LinearLayout>
<TextView
andROId:id="@+id/text"/>
<ImageView
android:id="@+id/icon"/>
</LinearLayout>
然后我就在想,在同一个布局文件中,是不允许同名(同id)的,不然就会报错,像这样:
<LinearLayout>
<TextView
android:id="@+id/text"/>
<ImageView
android:id="@+id/text"/> <!-- Error: text作为id已经存在了 -->
</LinearLayout>
但是在有层次嵌套的布局中,允许同名的id,那么findViewById会找到哪一个呢?
为了得到这个问题的答案,我首先去grepcode上搜了一下ViewGroup.findViewById()的源码实现
可以看到,ViewGroup去findViewById的时候,先把自己的子元素都拿出来,遍历他们,然后调用它们的findViewById,想象一下,如果子元素是个View,那么id只要配对上了,就直接返回了,如果子元素是个ViewGroup,那么就会继续调用子ViewGroup的这个方法。显然,这是一个深度优先的find。
为了验证这个深度优先,我构造了一个场景。先用文字来描述一下:在LinearLayout里面有一个ListView和一个TextView(这个TextView的id是text),然后ListView用数据去填充一些item,item的布局里面都是id为text的TextView。
然后,我在onCreate的时候去findViewById(R.id.text),会获取到哪一个TextView呢?
a.获取到LinearLayout里面的TextView
b.获取到ListView里面第一个item中的TextView
实验结果是:
在onCreate去findView的时候,获取的是LinearLayout里面的TextView。但是我postDelay在去find一遍的时候,获取到的就是ListView里面的TextView了。
下图所示:fuck是LinearLayout里面的TextView,shit是ListView中item的TextView
显然,onCreate的时候,Listview尚未被item填充,因此它的children实际上是空的,因此没法进行深度的遍历,找不到任何东西,当ListView已经被填充了,那么findViewById以深度遍历的形式去遍历,那么就会优先找到里面的元素。
因此,在给自定义布局加id的时候,最好还是在前面加上一个命名空间,以防止不知何时的findViewById获取到错误的View导致bug
以上是脚本宝典为你收集整理的View.findViewById是深度优先的全部内容,希望文章能够帮你解决View.findViewById是深度优先的所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。