从Activity的findViewById方法进入
@Nullable
public <T extends View> T findViewById(@IdRes int id) {
return getWindow().findViewById(id);
}
**可以看到进入了Window的findViewById **
@Nullable
public <T extends View> T findViewById(@IdRes int id) {
return getDecorView().findViewById(id);
}
再是getDecorView的findViewById 顺带贴个图
点进上面的find方法
@Nullable
public final <T extends View> T findViewById(@IdRes int id) {
if (id == NO_ID) {
return null;
}
return findViewTraversal(id);
}
这边虽然调用的是View的find方法,但是这个getDecorView本质上获取到的是一个ViewGroup,看一下PhoneWindow的源码,调用installDecor,再调generateDecor,最后返回一个DecorView,这个是一个FrameLayout
@Override
public final @NonNull View getDecorView() {
if (mDecor == null || mForceDecorInstall) {
installDecor();//这里
}
return mDecor;
}
private void installDecor() {
mForceDecorInstall = false;
if (mDecor == null) {
mDecor = generateDecor(-1);//这里
.....
} else {
mDecor.setWindow(this);
}
.....
}
protected DecorView generateDecor(int featureId) {
.....
}
继续往下就是调用到ViewGroup的findViewById方法,但是ViewGroup中没有find方法,他父类是View,会走View的find方法
@Nullable
public final <T extends View> T findViewById(@IdRes int id) {
if (id == NO_ID) {
return null;
}
return findViewTraversal(id);
}
因为当前是一个ViewGroup,而ViewGroup重写findViewTraversal方法,最后调到ViewGroup的findViewTraversal中
@Override
protected <T extends View> T findViewTraversal(@IdRes int id) {
if (id == mID) {
return (T) 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 (T) v;
}
}
}
return null;
}
可以看出,这边是循环遍历当前ViewGroup中的子View,然后调用的也是View的find方法,然后View的find方法最后也会调用自身findViewTraversal,View的findViewTraversal方法就是,对比Id,相等就返回
protected <T extends View> T findViewTraversal(@IdRes int id) {
if (id == mID) {
return (T) this;
}
return null;
}