Window初步认识

Window

该类是一个抽象类,提供了绘制窗口的一组通用API。

PhoneWindow

该类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了 一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。

DecorView

该类是一个FrameLayout的子类,并且是PhoneWindow的内部变量,该类就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等 。最重要的一点是,它是所有应用窗口的根View 。

包含ContentView和其他(StatusBar,ActionBar、ToolBar等)

ContentView

真正包含我们写的Layout的父布局,是DecorView的一个子类,可以通过findViewById(com.android.internal.R.id.content)拿到该对象。

生成ContentView的源码参考

//generateLayout
protected ViewGroup generateLayout(DecorView 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;
    } 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);
    //ID_ANDROID_CONTENT = com.android.internal.R.id.conten
  ...
}

通过源码会发现会根据设置主题的不同,ContentView的具体实现layout会不一样!举例说明screen_action_bar.xml(有actionBar)和screen_custom_title.xml(无actionBar)

  • screen_action_bar.xml

    
    
        
        
    
    

  • screen_custom_title.xml

    
    

    
    
    

setContentView()

Activity的setContetnView()最后会调用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)) {
            //如已经存在,会将之前的View都全部移除掉,所以setContentView可以反复调用
            mContentParent.removeAllViews();
        }

        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                    getContext());
            transitionTo(newScene);
        } else {
            mLayoutInflater.inflate(layoutResID, mContentParent);
        }
        mContentParent.requestApplyInsets();
        ...
    }

DectorView是在首次setContentView的时候才进行初始化的

    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);
        }
        ...
    }

参考 http://blog.csdn.net/qinjuning/article/details/7226787

你可能感兴趣的:(Window初步认识)