想必大家都写过Activity中onCreate函数里的setContentView(R.layout.main);这行代码吧。 这行代码是如何将我们的布局显示到Activity里的?今天就带大家来解析一番。
首先,我们进入到Activity的setContentView函数里,代码如下:
  
   - 
    
     
    
    
     
      /**
     
    
- 
    
     
    
    
     
       * Set the activity content from a layout resource. The resource will be
     
    
- 
    
     
    
    
     
       * inflated, adding all top-level views to the activity.
     
    
- 
    
     
    
    
     
       *
     
    
- 
    
     
    
    
     
       * @param layoutResID Resource ID to be inflated.
     
    
- 
    
     
    
    
     
       *
     
    
- 
    
     
    
    
     
       * @see #setContentView(android.view.View)
     
    
- 
    
     
    
    
     
       * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
     
    
- 
    
     
    
    
     
       */
     
    
- 
    
     
    
    
     
      public void setContentView(@LayoutRes int layoutResID) {
     
    
- 
    
     
    
    
     
       getWindow().setContentView(layoutResID);
     
    
- 
    
     
    
    
     
       initWindowDecorActionBar();
     
    
- 
    
     
    
    
     
      }
     
    
 我们发现它的内部实质是调用了getWindow().setContentView(layoutResID)。那我们就来看一下这个getWindow(),进入后代码如下:
  
   - 
    
     
    
    
     
      public Window getWindow() {
     
    
- 
    
     
    
    
      return mWindow;
     
    
- 
    
     
    
    
     
      }
     
    
 我看了下Window类,发现它是一个抽象类,后来找到了它的实现类是PhoneWindow,那我们就看PhoneWindow的setContentView函数,代码如下:
  
   - 
    
     
    
    
      @Override
     
    
- 
    
     
    
    
      public void setContentView(int layoutResID) {
     
    
- 
    
     
    
    
      // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
     
    
- 
    
     
    
    
      // decor, when theme attributes and the like are crystalized. Do not check the feature
     
    
- 
    
     
    
    
      // before this happens.
     
    
- 
    
     
    
    
      if (mContentParent == null) {
     
    
- 
    
     
    
    
     
       installDecor();
     
    
- 
    
     
    
    
     
       } 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.requestApplyInsets();
     
    
- 
    
     
    
    
      final Callback cb = getCallback();
     
    
- 
    
     
    
    
      if (cb != null && !isDestroyed()) {
     
    
- 
    
     
    
    
     
       cb.onContentChanged();
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       mContentParentExplicitlySet = true;
     
    
- 
    
     
    
    
     
       }
     
    
 我们先看一下installDecor()函数,它目的是创建一个DectorView ,该view继承于FrameLayout,installDecor()的代码如下:
  
   - 
    
     
    
    
      private void installDecor() {
     
    
- 
    
     
    
    
     
       mForceDecorInstall = false;
     
    
- 
    
     
    
    
      if (mDecor == null) {
     
    
- 
    
     
    
    
     
       mDecor = generateDecor(-1);
     
    
- 
    
     
    
    
     
       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);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      // Set up decor part of UI to ignore fitsSystemWindows if appropriate.
     
    
- 
    
     
    
    
     
       mDecor.makeOptionalFitsSystemWindows();
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       。。。。。。
     
    
- 
    
     
    
    
     
       }
     
    
 其中第4行:generateDecor函数,就创建了一个继承于FrameLayout的DectorView视图,其中mDector的类型是DectorView;
还有 mContentParent = generateLayout(mDecor)这行代码,它的作用是往DectorView里添加了一个ID为R.id.content视图。然后返回了这个content视图,并赋值给mContentParent。 这个R.id.content视图是干什么的呢?在此提前剧透一下,它就是用来包裹我们setContentView(R.layout.main).中 main.xml布局的,换句话说,它是我们页面布局的根布局。
那好,那当前我们所认识的视图结构图就是:PhoneWindow是Activity的一个窗口,这个PhoneWindow里有一个DectorView,它是这个Activity的根布局,因为它里面的mContentParent(R.id.content)包裹了main.xml里的所有布局视图。
视图结构示意图如下:

上图是我们画的一个Activity视图结构图,我们深入到mContentParent = generateLayout(mDecor),分析这个generateLayout函数里,看看能不能再完善一下我们的视图结构图。generateLayout(mDecor)的代码如下:
  
   - 
    
     
    
    
     
      protected ViewGroup generateLayout(DecorView decor) {
     
    
- 
    
     
    
    
     
       // Apply data from current theme.
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       TypedArray a = getWindowStyle();
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       if (false) {
     
    
- 
    
     
    
    
     
       System.out.println("From style:");
     
    
- 
    
     
    
    
     
       String s = "Attrs:";
     
    
- 
    
     
    
    
     
       for (int i = 0; i < R.styleable.Window.length; i++) {
     
    
- 
    
     
    
    
     
       s = s + " " + Integer.toHexString(R.styleable.Window[i]) + "="
     
    
- 
    
     
    
    
     
       + a.getString(i);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       System.out.println(s);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       mIsFloating = a.getBoolean(R.styleable.Window_windowIsFloating, false);
     
    
- 
    
     
    
    
     
       int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR)
     
    
- 
    
     
    
    
     
       & (~getForcedWindowFlags());
     
    
- 
    
     
    
    
     
       if (mIsFloating) {
     
    
- 
    
     
    
    
     
       setLayout(WRAP_CONTENT, WRAP_CONTENT);
     
    
- 
    
     
    
    
     
       setFlags(0, flagsToUpdate);
     
    
- 
    
     
    
    
     
       } else {
     
    
- 
    
     
    
    
     
       setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
     
    
- 
    
     
    
    
     
       requestFeature(FEATURE_NO_TITLE);
     
    
- 
    
     
    
    
     
       } else if (a.getBoolean(R.styleable.Window_windowActionBar, false)) {
     
    
- 
    
     
    
    
     
       // Don't allow an action bar if there is no title.
     
    
- 
    
     
    
    
     
       requestFeature(FEATURE_ACTION_BAR);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowActionBarOverlay, false)) {
     
    
- 
    
     
    
    
     
       requestFeature(FEATURE_ACTION_BAR_OVERLAY);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowActionModeOverlay, false)) {
     
    
- 
    
     
    
    
     
       requestFeature(FEATURE_ACTION_MODE_OVERLAY);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowSwipeToDismiss, false)) {
     
    
- 
    
     
    
    
     
       requestFeature(FEATURE_SWIPE_TO_DISMISS);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowFullscreen, false)) {
     
    
- 
    
     
    
    
     
       setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowTranslucentStatus,
     
    
- 
    
     
    
    
     
       false)) {
     
    
- 
    
     
    
    
     
       setFlags(FLAG_TRANSLUCENT_STATUS, FLAG_TRANSLUCENT_STATUS
     
    
- 
    
     
    
    
     
       & (~getForcedWindowFlags()));
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowTranslucentNavigation,
     
    
- 
    
     
    
    
     
       false)) {
     
    
- 
    
     
    
    
     
       setFlags(FLAG_TRANSLUCENT_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION
     
    
- 
    
     
    
    
     
       & (~getForcedWindowFlags()));
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowOverscan, false)) {
     
    
- 
    
     
    
    
     
       setFlags(FLAG_LAYOUT_IN_OVERSCAN, FLAG_LAYOUT_IN_OVERSCAN&(~getForcedWindowFlags()));
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowShowWallpaper, false)) {
     
    
- 
    
     
    
    
     
       setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags()));
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowEnableSplitTouch,
     
    
- 
    
     
    
    
     
       getContext().getApplicationInfo().targetSdkVersion
     
    
- 
    
     
    
    
     
       >= android.os.Build.VERSION_CODES.HONEYCOMB)) {
     
    
- 
    
     
    
    
     
       setFlags(FLAG_SPLIT_TOUCH, FLAG_SPLIT_TOUCH&(~getForcedWindowFlags()));
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       a.getValue(R.styleable.Window_windowMinWidthMajor, mMinWidthMajor);
     
    
- 
    
     
    
    
     
       a.getValue(R.styleable.Window_windowMinWidthMinor, mMinWidthMinor);
     
    
- 
    
     
    
    
     
       if (DEBUG) Log.d(TAG, "Min width minor: " + mMinWidthMinor.coerceToString()
     
    
- 
    
     
    
    
     
       + ", major: " + mMinWidthMajor.coerceToString());
     
    
- 
    
     
    
    
     
       if (a.hasValue(R.styleable.Window_windowFixedWidthMajor)) {
     
    
- 
    
     
    
    
     
       if (mFixedWidthMajor == null) mFixedWidthMajor = new TypedValue();
     
    
- 
    
     
    
    
     
       a.getValue(R.styleable.Window_windowFixedWidthMajor,
     
    
- 
    
     
    
    
     
       mFixedWidthMajor);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (a.hasValue(R.styleable.Window_windowFixedWidthMinor)) {
     
    
- 
    
     
    
    
     
       if (mFixedWidthMinor == null) mFixedWidthMinor = new TypedValue();
     
    
- 
    
     
    
    
     
       a.getValue(R.styleable.Window_windowFixedWidthMinor,
     
    
- 
    
     
    
    
     
       mFixedWidthMinor);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (a.hasValue(R.styleable.Window_windowFixedHeightMajor)) {
     
    
- 
    
     
    
    
     
       if (mFixedHeightMajor == null) mFixedHeightMajor = new TypedValue();
     
    
- 
    
     
    
    
     
       a.getValue(R.styleable.Window_windowFixedHeightMajor,
     
    
- 
    
     
    
    
     
       mFixedHeightMajor);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (a.hasValue(R.styleable.Window_windowFixedHeightMinor)) {
     
    
- 
    
     
    
    
     
       if (mFixedHeightMinor == null) mFixedHeightMinor = new TypedValue();
     
    
- 
    
     
    
    
     
       a.getValue(R.styleable.Window_windowFixedHeightMinor,
     
    
- 
    
     
    
    
     
       mFixedHeightMinor);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowContentTransitions, false)) {
     
    
- 
    
     
    
    
     
       requestFeature(FEATURE_CONTENT_TRANSITIONS);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) {
     
    
- 
    
     
    
    
     
       requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       mIsTranslucent = a.getBoolean(R.styleable.Window_windowIsTranslucent, false);
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       final Context context = getContext();
     
    
- 
    
     
    
    
     
       final int targetSdk = context.getApplicationInfo().targetSdkVersion;
     
    
- 
    
     
    
    
     
       final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB;
     
    
- 
    
     
    
    
     
       final boolean targetPreIcs = targetSdk < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
     
    
- 
    
     
    
    
     
       final boolean targetPreL = targetSdk < android.os.Build.VERSION_CODES.LOLLIPOP;
     
    
- 
    
     
    
    
     
       final boolean targetHcNeedsOptions = context.getResources().getBoolean(
     
    
- 
    
     
    
    
     
       R.bool.target_honeycomb_needs_options_menu);
     
    
- 
    
     
    
    
     
       final boolean noActionBar = !hasFeature(FEATURE_ACTION_BAR) || hasFeature(FEATURE_NO_TITLE);
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) {
     
    
- 
    
     
    
    
     
       setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE);
     
    
- 
    
     
    
    
     
       } else {
     
    
- 
    
     
    
    
     
       setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_FALSE);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (!mForcedStatusBarColor) {
     
    
- 
    
     
    
    
     
       mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (!mForcedNavigationBarColor) {
     
    
- 
    
     
    
    
     
       mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
     
    
- 
    
     
    
    
     
       mNavigationBarDividerColor = a.getColor(R.styleable.Window_navigationBarDividerColor,
     
    
- 
    
     
    
    
     
       0x00000000);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       WindowManager.LayoutParams params = getAttributes();
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       // Non-floating windows on high end devices must put up decor beneath the system bars and
     
    
- 
    
     
    
    
     
       // therefore must know about visibility changes of those.
     
    
- 
    
     
    
    
     
       if (!mIsFloating) {
     
    
- 
    
     
    
    
     
       if (!targetPreL && a.getBoolean(
     
    
- 
    
     
    
    
     
       R.styleable.Window_windowDrawsSystemBarBackgrounds,
     
    
- 
    
     
    
    
     
       false)) {
     
    
- 
    
     
    
    
     
       setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
     
    
- 
    
     
    
    
     
       FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (mDecor.mForceWindowDrawsStatusBarBackground) {
     
    
- 
    
     
    
    
     
       params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
     
    
- 
    
     
    
    
     
       decor.setSystemUiVisibility(
     
    
- 
    
     
    
    
     
       decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)) {
     
    
- 
    
     
    
    
     
       decor.setSystemUiVisibility(
     
    
- 
    
     
    
    
     
       decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (a.hasValue(R.styleable.Window_windowLayoutInDisplayCutoutMode)) {
     
    
- 
    
     
    
    
     
       int mode = a.getInt(R.styleable.Window_windowLayoutInDisplayCutoutMode, -1);
     
    
- 
    
     
    
    
     
       if (mode < LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
     
    
- 
    
     
    
    
     
       || mode > LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER) {
     
    
- 
    
     
    
    
     
       throw new UnsupportedOperationException("Unknown windowLayoutInDisplayCutoutMode: "
     
    
- 
    
     
    
    
     
       + a.getString(R.styleable.Window_windowLayoutInDisplayCutoutMode));
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       params.layoutInDisplayCutoutMode = mode;
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion
     
    
- 
    
     
    
    
     
       >= android.os.Build.VERSION_CODES.HONEYCOMB) {
     
    
- 
    
     
    
    
     
       if (a.getBoolean(
     
    
- 
    
     
    
    
     
       R.styleable.Window_windowCloseOnTouchOutside,
     
    
- 
    
     
    
    
     
       false)) {
     
    
- 
    
     
    
    
     
       setCloseOnTouchOutsideIfNotSet(true);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       if (!hasSoftInputMode()) {
     
    
- 
    
     
    
    
     
       params.softInputMode = a.getInt(
     
    
- 
    
     
    
    
     
       R.styleable.Window_windowSoftInputMode,
     
    
- 
    
     
    
    
     
       params.softInputMode);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       if (a.getBoolean(R.styleable.Window_backgroundDimEnabled,
     
    
- 
    
     
    
    
     
       mIsFloating)) {
     
    
- 
    
     
    
    
     
       /* All dialogs should have the window dimmed */
     
    
- 
    
     
    
    
     
       if ((getForcedWindowFlags()&WindowManager.LayoutParams.FLAG_DIM_BEHIND) == 0) {
     
    
- 
    
     
    
    
     
       params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (!haveDimAmount()) {
     
    
- 
    
     
    
    
     
       params.dimAmount = a.getFloat(
     
    
- 
    
     
    
    
     
       android.R.styleable.Window_backgroundDimAmount, 0.5f);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       if (params.windowAnimations == 0) {
     
    
- 
    
     
    
    
     
       params.windowAnimations = a.getResourceId(
     
    
- 
    
     
    
    
     
       R.styleable.Window_windowAnimationStyle, 0);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       // The rest are only done if this window is not embedded; otherwise,
     
    
- 
    
     
    
    
     
       // the values are inherited from our container.
     
    
- 
    
     
    
    
     
       if (getContainer() == null) {
     
    
- 
    
     
    
    
     
       if (mBackgroundDrawable == null) {
     
    
- 
    
     
    
    
     
       if (mBackgroundResource == 0) {
     
    
- 
    
     
    
    
     
       mBackgroundResource = a.getResourceId(
     
    
- 
    
     
    
    
     
       R.styleable.Window_windowBackground, 0);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (mFrameResource == 0) {
     
    
- 
    
     
    
    
     
       mFrameResource = a.getResourceId(R.styleable.Window_windowFrame, 0);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       mBackgroundFallbackResource = a.getResourceId(
     
    
- 
    
     
    
    
     
       R.styleable.Window_windowBackgroundFallback, 0);
     
    
- 
    
     
    
    
     
       if (false) {
     
    
- 
    
     
    
    
     
       System.out.println("Background: "
     
    
- 
    
     
    
    
     
       + Integer.toHexString(mBackgroundResource) + " Frame: "
     
    
- 
    
     
    
    
     
       + Integer.toHexString(mFrameResource));
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       if (mLoadElevation) {
     
    
- 
    
     
    
    
     
       mElevation = a.getDimension(R.styleable.Window_windowElevation, 0);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       mClipToOutline = a.getBoolean(R.styleable.Window_windowClipToOutline, false);
     
    
- 
    
     
    
    
     
       mTextColor = a.getColor(R.styleable.Window_textColor, Color.TRANSPARENT);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       // Inflate the window decor.
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
       int layoutResource;
     
    
- 
    
     
    
    
     
       int features = getLocalFeatures();
     
    
- 
    
     
    
    
     
       // System.out.println("Features: 0x" + Integer.toHexString(features));
     
    
- 
    
     
    
    
     
       if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
     
    
- 
    
     
    
    
     
       layoutResource = R.layout.screen_swipe_dismiss;
     
    
- 
    
     
    
    
     
       setCloseOnSwipeEnabled(true);
     
    
- 
    
     
    
    
     
       } else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
     
    
- 
    
     
    
    
     
       if (mIsFloating) {
     
    
- 
    
     
    
    
     
       TypedValue res = new TypedValue();
     
    
- 
    
     
    
    
     
       getContext().getTheme().resolveAttribute(
     
    
- 
    
     
    
    
     
       R.attr.dialogTitleIconsDecorLayout, res, true);
     
    
- 
    
     
    
    
     
       layoutResource = res.resourceId;
     
    
- 
    
     
    
    
     
       } else {
     
    
- 
    
     
    
    
     
       layoutResource = 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 = 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(
     
    
- 
    
     
    
    
     
       R.attr.dialogCustomTitleDecorLayout, res, true);
     
    
- 
    
     
    
    
     
       layoutResource = res.resourceId;
     
    
- 
    
     
    
    
     
       } else {
     
    
- 
    
     
    
    
     
       layoutResource = 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(
     
    
- 
    
     
    
    
     
       R.attr.dialogTitleDecorLayout, res, true);
     
    
- 
    
     
    
    
     
       layoutResource = res.resourceId;
     
    
- 
    
     
    
    
     
       } else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
     
    
- 
    
     
    
    
     
       layoutResource = a.getResourceId(
     
    
- 
    
     
    
    
     
       R.styleable.Window_windowActionBarFullscreenDecorLayout,
     
    
- 
    
     
    
    
     
       R.layout.screen_action_bar);
     
    
- 
    
     
    
    
     
       } else {
     
    
- 
    
     
    
    
     
       layoutResource = R.layout.screen_title;
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       // System.out.println("Title!");
     
    
- 
    
     
    
    
     
       } else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
     
    
- 
    
     
    
    
     
       layoutResource = R.layout.screen_simple_overlay_action_mode;
     
    
- 
    
     
    
    
     
       } else {
     
    
- 
    
     
    
    
     
       // Embedded, so no decoration is needed.
     
    
- 
    
     
    
    
     
       layoutResource = R.layout.screen_simple;
     
    
- 
    
     
    
    
     
       // System.out.println("Simple!");
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       mDecor.startChanging();
     
    
- 
    
     
    
    
     
       mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
     
    
- 
    
     
    
    
     
       if (contentParent == null) {
     
    
- 
    
     
    
    
     
       throw new RuntimeException("Window couldn't find content container view");
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) {
     
    
- 
    
     
    
    
     
       ProgressBar progress = getCircularProgressBar(false);
     
    
- 
    
     
    
    
     
       if (progress != null) {
     
    
- 
    
     
    
    
     
       progress.setIndeterminate(true);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
     
    
- 
    
     
    
    
     
       registerSwipeCallbacks(contentParent);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       // Remaining setup -- of background and title -- that only applies
     
    
- 
    
     
    
    
     
       // to top-level windows.
     
    
- 
    
     
    
    
     
       if (getContainer() == null) {
     
    
- 
    
     
    
    
     
       final Drawable background;
     
    
- 
    
     
    
    
     
       if (mBackgroundResource != 0) {
     
    
- 
    
     
    
    
     
       background = getContext().getDrawable(mBackgroundResource);
     
    
- 
    
     
    
    
     
       } else {
     
    
- 
    
     
    
    
     
       background = mBackgroundDrawable;
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       mDecor.setWindowBackground(background);
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       final Drawable frame;
     
    
- 
    
     
    
    
     
       if (mFrameResource != 0) {
     
    
- 
    
     
    
    
     
       frame = getContext().getDrawable(mFrameResource);
     
    
- 
    
     
    
    
     
       } else {
     
    
- 
    
     
    
    
     
       frame = null;
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       mDecor.setWindowFrame(frame);
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       mDecor.setElevation(mElevation);
     
    
- 
    
     
    
    
     
       mDecor.setClipToOutline(mClipToOutline);
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (mTitle != null) {
     
    
- 
    
     
    
    
     
       setTitle(mTitle);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       if (mTitleColor == 0) {
     
    
- 
    
     
    
    
     
       mTitleColor = mTextColor;
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
       setTitleColor(mTitleColor);
     
    
- 
    
     
    
    
     
       }
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       mDecor.finishChanging();
     
    
- 
    
     
    
    
     
      
     
    
- 
    
     
    
    
     
       return contentParent;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
     
      
     
    
 我们主要看标注了红色字体的代码,在代码的最后它返回了contentParent,也就是我们所说的R.id.content那个根视图。
在代码的开始部分,有好几段类似以下这样的代码:
if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) { requestFeature(FEATURE_NO_TITLE); }
这行代码的作用是读取Windows风格属性,比如NoTitle, 然后调用requestFeature(FEATURE_NO_TITLE),想必这个requestFeature函数大家都用过吧,比如我们想用代码来实现全屏无标题,需要在setContentView之前调用这个函数。代码看到这里,我们的setContentView还没有调用完毕,这也就是说requestFeature必须在写在Activity的setContentView之前。
然后值得注意的是 layoutResource = R.layout.screen_simple; 这行代码,有几处都是根据features的值来加载相应的布局。
最终调用mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);把这个layoutResource添加到了Dectorview里面。在这里我们就会提出疑问,根据前面那个View结构图,不是说Dectorview下面直接包含的是R.id.content视图吗?这正是我们要完善的部分。我们先来看看 layoutResource = R.layout.screen_simple这种情况下screen_title布局里到底包含什么,从SDK源码中我们找到了screen_title布局的XML代码如下:
  
   - 
    
     
    
    
     
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     
    
- 
    
     
    
    
      android:layout_width="match_parent"
     
    
- 
    
     
    
    
      android:layout_height="match_parent"
     
    
- 
    
     
    
    
      android:fitsSystemWindows="true"
     
    
- 
    
     
    
    
      android:orientation="vertical">
     
    
- 
    
     
    
    
      <ViewStub android:id="@+id/action_mode_bar_stub"
     
    
- 
    
     
    
    
      android:inflatedId="@+id/action_mode_bar"
     
    
- 
    
     
    
    
      android:layout="@layout/action_mode_bar"
     
    
- 
    
     
    
    
      android:layout_width="match_parent"
     
    
- 
    
     
    
    
      android:layout_height="wrap_content"
     
    
- 
    
     
    
    
      android:theme="?attr/actionBarTheme" />
     
    
- 
    
     
    
    
      <FrameLayout
     
    
- 
    
     
    
    
      android:id="@android:id/content"
     
    
- 
    
     
    
    
      android:layout_width="match_parent"
     
    
- 
    
     
    
    
      android:layout_height="match_parent"
     
    
- 
    
     
    
    
      android:foregroundInsidePadding="false"
     
    
- 
    
     
    
    
      android:foregroundGravity="fill_horizontal|top"
     
    
- 
    
     
    
    
      android:foregrou
     
    
 
哇,看到那个id/content的FrameLayout了吗?它正是我们所说的R.id.content视图,那我们的View结构图的大方向没有错!只是上面多了个ViewStub,这个ViewStub用来加载不同的标题栏,是一个可以被多种标题布局替换的一个块布局。Ok,那我们现在就来完善一下我们上面的View结构图:

就是DectorView下面多了一层布局simple_title,然后R.id.content是包含在simple_title里面的。
我们现在总结一下,Activity的布局结构是这样的 PhoneWindow显示----DecotorView-----R.layout.simple_title----R.id.content----R.layout.main(我们自己的布局)。今天就先分析Activity的布局结构到这里,改天再看看这些布局是如何绘制到PhoneWindow上去的(也就是说绘制到Activity上)。
文章来源: blog.csdn.net,作者:冉航--小虾米,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/gaoxiaoweiandy/article/details/95216719