为什么requestWindowFeature()方法要在setContentView()方法之前调用?

日常开发中偶尔遇到需要修改标题栏样式的情况,这个时候就需要用到requestWindowFeature(int featureId)来设置窗口样式。

featureId有如下几种值:

  1. DEFAULT_FEATURES:系统默认状态,一般不需要指定
  2. FEATURE_CONTEXT_MENU:启用ContextMenu,默认该项已启用,一般无需指定
  3. FEATURE_CUSTOM_TITLE:自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时
  4. FEATURE_INDETERMINATE_PROGRESS:不确定的进度
  5. FEATURE_LEFT_ICON:标题栏左侧的图标
  6. FEATURE_NO_TITLE:无标题
  7. FEATURE_OPTIONS_PANEL:启用“选项面板”功能,默认已启用。
  8. FEATURE_PROGRESS:进度指示器功能
  9. FEATURE_RIGHT_ICON:标题栏右侧的图标
    各自的样式大家可以自己尝试一下,我们这次只是探讨为什么requestWindowFeature方法要在setContentView()方法之前调用。

要理解为什么requestWindowFeature()方法要在setContentView()方法之前调用,我们首先要看一下Android的窗口的UI架构。

为什么requestWindowFeature()方法要在setContentView()方法之前调用?_第1张图片
Activity的UI架构

如图所示,每个Activity中都包含一个Window类的对象,一般这个Window类的对象是由PhoneWindow实现的,也就是Avtivity内部有一个PhoneWindow的对象。而这个PhoneWindow对象会将一个DecorView对象设置成整个窗口的根View。这样看来也就说,整个Activity显示的是一个DecorView。而在DecorView内部将显示内容分为TitleView和ContentView两个部分。ContentView大家都比较熟悉,它是一个ID为content的FrameLayout,我们通过setContentView()设置的布局就会被添加到这个FrameLayout上。
为什么requestWindowFeature()方法要在setContentView()方法之前调用?_第2张图片
这里写图片描述

DecorView中的布局关系如上图,我们看一下setContentView方法的代码。

    public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

首先它会设置FrameLayout的布局,之后回初始化ActionBar。看到这里我们就明白了,如果在setContentView方法之后设置requestWindowFeature()方法的话,由于已经初始化了ActionBar,所以并不会引起UI显示上的变化,必须在setContentView之前调用requestWindowFeature()方法才能在ActionBar初始化的时候影响它的显示。

你可能感兴趣的:(为什么requestWindowFeature()方法要在setContentView()方法之前调用?)