关于Activity setContentView()方法

关于Android  setContentView

1.setContentView 方法,从下面的代码可以看出,真正setContentView的是Window,而这个Window的实现就是PhoneWindow

 public void setContentView(int layoutResID) {
     getWindow().setContentView(layoutResID);
     initActionBar();
 }

2,继续看 getWindow().setContentView(layoutResID)方法,如下

@Override
public void setContentView(int layoutResID) {
    if (mContentParent == null) {
        installDecor();
    } else {
        mContentParent.removeAllViews();
    }
    //我们自己定义的Activity的布局文件被填充到mContentParent中
    mLayoutInflater.inflate(layoutResID, mContentParent);
    final Callback cb = getCallback();
    if (cb != null && !isDestroyed()) {
        cb.onContentChanged();
    }
}

 3.从mLayoutInflater.inflate(layoutResID, mContentParent);看出我们自己定义的Activity的布局文件被填充到mContentParent中,那么mContentParent是什么呢, 接着看installDecor();,如下

private void installDecor() {
        if (mDecor == null) {
            mDecor = generateDecor();
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            mDecor.setIsRootNamespace(true);
            //...
        }

        if (mContentParent == null) {
            //这里生成了包裹我们布局文件的mContentParent
            mContentParent = generateLayout(mDecor);
            mTitleView = (TextView) findViewById(com.android.internal.R.id.title);
            if (mTitleView != null) {
                
                
            } else {
                mActionBar=(ActionBarView)findViewById(com.android.internal.R.id.action_bar);                        
                if (mActionBar != null) {
                    
                }
            }
        }
   }

  public View findViewById(int id) {
       return getDecorView().findViewById(id);
  }


  public DecorView(Context context, int featureId) {
        super(context);
        mFeatureId = featureId;
  }

  protected DecorView generateDecor() {
       return new DecorView(getContext(), -1);
  }

 4.generateLayout(mDecor)方法

protected ViewGroup generateLayout(DecorView decor) {
    // Apply data from current theme.
    TypedArray a = getWindowStyle();
    //...Window_windowIsFloating,Window_windowNoTitle,Window_windowActionBar...
    

    if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) {
        requestFeature(FEATURE_NO_TITLE);
    }
    //...
    if (a.getBoolean(com.android.internal.R.styleable.Window_windowFullscreen, false)) {
        setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
    }

    WindowManager.LayoutParams params = getAttributes();

    // Inflate the window decor.
    int layoutResource;
    int features = getLocalFeatures();
    // System.out.println("Features: 0x" + Integer.toHexString(features));
    if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
        if (mIsFloating) {
            TypedValue res = new TypedValue();
            getContext().getTheme().resolveAttribute(
                    com.android.internal.R.attr.dialogTitleIconsDecorLayout, res, true);
            layoutResource = res.resourceId;
        } else {
            layoutResource = com.android.internal.R.layout.screen_title_icons;
        }
        // XXX Remove this once action bar supports these features.
        removeFeature(FEATURE_ACTION_BAR);
        // System.out.println("Title Icons!");
    } else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0
            && (features & (1 << FEATURE_ACTION_BAR)) == 0) {
        // Special case for a window with only a progress bar (and title).
        // XXX Need to have a no-title version of embedded windows.
        layoutResource = com.android.internal.R.layout.screen_progress;
        // System.out.println("Progress!");
    } else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) {
        // Special case for a window with a custom title.
        // If the window is floating, we need a dialog layout
        if (mIsFloating) {
            TypedValue res = new TypedValue();
            getContext().getTheme().resolveAttribute(
                    com.android.internal.R.attr.dialogCustomTitleDecorLayout, res, true);
            layoutResource = res.resourceId;
        } else {
            layoutResource = com.android.internal.R.layout.screen_custom_title;
        }
        // XXX Remove this once action bar supports these features.
        removeFeature(FEATURE_ACTION_BAR);
    } else if ((features & (1 << FEATURE_NO_TITLE)) == 0) {
        // If no other features and not embedded, only need a title.
        // If the window is floating, we need a dialog layout
        if (mIsFloating) {
            TypedValue res = new TypedValue();
            getContext().getTheme().resolveAttribute(
                    com.android.internal.R.attr.dialogTitleDecorLayout, res, true);
            layoutResource = res.resourceId;
        } else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
            layoutResource = com.android.internal.R.layout.screen_action_bar;
        } else {
            layoutResource = com.android.internal.R.layout.screen_title;
        }
        // System.out.println("Title!");
    } else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
        layoutResource = com.android.internal.R.layout.screen_simple_overlay_action_mode;
    } else {
        // Embedded, so no decoration is needed.
        layoutResource = com.android.internal.R.layout.screen_simple;
        // System.out.println("Simple!");
    }


    View in = mLayoutInflater.inflate(layoutResource, null);

    //从这里可以看出decorView添加了layoutResource填充成的View,这个View
    //就是系统预制的布局文件也可以理解为“模板布局文件”,这个文件里面有个id为ID_ANDROID_CONTENT
    //的FrameLayout,我们自定义的Activity的布局文件填充成View后就添加到这个FrameLayout了

    decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));

    //或者id为ID_ANDROID_CONTENT的控件,其实就是FrameLayout
    //从这里可以知道,contentParent就是为id为ID_ANDROID_CONTENT的FrameLayout
    //我们的布局文件就是添加到这个容器里面了

    ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
    //...

    return contentParent;
    
}

参考博客:

http://blog.csdn.net/lmj623565791/article/details/41894125

你可能感兴趣的:(Android,源码)