setContentView源码阅读
源码阅读推荐一个地址, 安卓源码,studio没有的源码在这个地址可以查到
Activity
public void setContentView(@LayoutRes int layoutResID) {
//调用getWindow的setContentView
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
- PhoneWindow源码
@Override
397 public void setContentView(int layoutResID) {
398 // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
399 // decor, when theme attributes and the like are crystalized. Do not check the feature
400 // before this happens.
401 if (mContentParent == null) {
// -----------这里我们需要关注下,初始化一个mContentParent----------------
402 installDecor();
403 } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
404 mContentParent.removeAllViews();
405 }
406
407 if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
408 final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
409 getContext());
410 transitionTo(newScene);
411 } else {
// -----------这里我们需要关注下,从上面会传下来一个mContentParent----------------
412 mLayoutInflater.inflate(layoutResID, mContentParent);
413 }
414 mContentParent.requestApplyInsets();
415 final Callback cb = getCallback();
416 if (cb != null && !isDestroyed()) {
417 cb.onContentChanged();
418 }
419 mContentParentExplicitlySet = true;
420 }
- installDecor源码,只需要关注以下部分
private void installDecor() {
2616 mForceDecorInstall = false;
2617 if (mDecor == null) {
//这里追踪进去就是new 一个decorview
// return new DecorView(context, featureId, this, getAttributes());
2618 mDecor = generateDecor(-1);
2619 mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
2620 mDecor.setIsRootNamespace(true);
2621 if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
2622 mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
2623 }
2624 } else {
2625 mDecor.setWindow(this);
2626 }
2627 if (mContentParent == null) {
// 创建一个mContentParent
2628 mContentParent = generateLayout(mDecor);
2629
- generateLayout源码
2493 int layoutResource;//系统layout资源文件
2555 mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
//onResourcesLoaded这里进去,里面主要是实例化系统布局,并把布局加入到了DecorView
//final View root = inflater.inflate(layoutResource, null);
// mDecorCaptionView.addView(root, new ViewGroup.MarginLayoutParams(MATCH_PARENT,MATCH_PARENT));
//找一个android.R.id.content的FrameLayout
2557 ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
AppCompatActivity
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
public void setContentView(int resId) {
ensureSubDecor();
ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);
mAppCompatWindowCallback.getWrapped().onContentChanged();
}
extends Activity和AppCompateActivity的View的区别
// extends Activity mImageIv is ImageView
// extends AppCompatActivity mImageView is AppCompatImageView tint
// Log.e("TAG", "" + mImageIv);
AppCompateActivity创建View的时候会被拦截,不会走系统的LayoutInflater的创建,就会被替换掉一些特定的View
LayoutInflater布局导入
- LayoutInflater.from(this)获取的源码
// 获取系统的服务LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); // 从一个静态的Map集合
LayoutInflater.from(this) 第一个它是系统服务,它是我们的单例设计模式。单个实例在内存中只有一个事例。
- 实例化View的inflater方法的源码
View view;
if (mFactory2 != null) {
view = mFactory2.onCreateView(parent, name, context, attrs);
} else if (mFactory != null) {
view = mFactory.onCreateView(name, context, attrs);
} else {
view = null;
}
- view的拦截
LayoutInflater layoutInflater = LayoutInflater.from(this);
LayoutInflaterCompat.setFactory2(layoutInflater, new LayoutInflater.Factory2() {
@Nullable
@org.jetbrains.annotations.Nullable
@Override
public View onCreateView(@Nullable @org.jetbrains.annotations.Nullable View parent, @NonNull @NotNull String name, @NonNull @NotNull Context context, @NonNull @NotNull AttributeSet attrs) {
//拦截View的创建
if (name.equals("TextView")) {
return new TextView(MainActivity.this);
}
return null;
}