@act262
2017-05-24T14:26:19.000000Z
字数 942
阅读 1282
AndroidSource
在Activity中调用的findViewById
方法分析具体流程如下:
Activity中封装的方法
public View findViewById(@IdRes int id) {
return getWindow().findViewById(id);
}
也就是调用到Window的findViewById
方法
public View findViewById(@IdRes int id) {
return getDecorView().findViewById(id);
}
public abstract View getDecorView();
调用到View的findViewById
,再调用findViewTraversal
这个遍历方法
public final View findViewById(@IdRes int id) {
if (id < 0) {
return null;
}
return findViewTraversal(id);
}
// 遍历查找,由子类覆盖实现
protected View findViewTraversal(@IdRes int id) {
if (id == mID) {
return this;
}
return null;
}
这里的getDecorView具体实现类是DecorView
,继承自FrameLayout
,FrameLayout
中没有复写findViewTraversal
,其实现是在ViewGroup的findViewTraversal
实现的。
protected View findViewTraversal(@IdRes int id) {
if (id == mID) {
return this;
}
final View[] where = mChildren;
final int len = mChildrenCount;
// 遍历其子View来查找匹配Id的View
for (int i = 0; i < len; i++) {
View v = where[i];
// 这个View不属于root
if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
v = v.findViewById(id);
// 找到了返回
if (v != null) {
return v;
}
}
}
return null;
}