view如何被添加到窗口

直接通过源码来进行分析:
涉及相关类:Activity, PhoneWindow(extends Window), DecorView(extends FrameLayout);

1.创建顶层布局容器DecorView;
2.在顶层布局中加载基础布局viewGroup;
3.将ContentView添加到基础布局中的FrameLayout中;

先看流程:
Activity: setContentView() ->getWindow().setContentView(layoutResID)
PhoneWindow:setContentView() -> installDecor()

(->把布局添加到根布局中)
->generateDecor()创建DecorView容器
->generateLayout(mDecor):加载样式和不同的根布局,添加到DecorView中;
->初始化了布局容器contentParent;

PhoneWindo.java
 @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor();//这里是加载DecorView 和初始化 mContentParent  重点
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }

        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                    getContext());
            transitionTo(newScene);
        } else {
            mLayoutInflater.inflate(layoutResID, mContentParent);//把自己的布局添加到mContentParent中,完成,view的添加;
        }
        mContentParent.requestApplyInsets();
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
        mContentParentExplicitlySet = true;
    }
 private void installDecor() {
        mForceDecorInstall = false;
        if (mDecor == null) {
            mDecor = generateDecor(-1);//这里是初始化 DecorView 这是一个FrameLayout
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            mDecor.setIsRootNamespace(true);
            if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
                mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
            }
        } else {
            mDecor.setWindow(this);
        }
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);//这里是重点,完成主题、布局样式等,并初始化mContentParent
              ...
              ...
}
  protected ViewGroup generateLayout(DecorView decor) {
        // Apply data from current theme.
        TypedArray a = getWindowStyle();
...//主要是设置主题样式
...
  // Inflate the window decor.
        int layoutResource;//根据features  获取一个layout
        int features = getLocalFeatures();
...
        mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);//把layout作为decorview的根布局
        ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
        if (contentParent == null) {
            throw new RuntimeException("Window couldn't find content container view");
        }
...
return contentParent;
}

在获取到contentParent后,在PhoneWindow中的setContentViw中 mLayoutInflater.inflate(layoutResID, mContentParent);完成了自己的资源添加到了窗口;


decorView.PNG

你可能感兴趣的:(view如何被添加到窗口)