日常开发中偶尔遇到需要修改标题栏样式的情况,这个时候就需要用到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架构。 如图所示,每个Activity中都包含一个Window类的对象,一般这个Window类的对象是由PhoneWindow实现的,也就是Avtivity内部有一个PhoneWindow的对象。而这个PhoneWindow对象会将一个DecorView对象设置成整个窗口的根View。这样看来也就说,整个Activity显示的是一个DecorView。而在DecorView内部将显示内容分为TitleView和ContentView两个部分。ContentView大家都比较熟悉,它是一个ID为content的FrameLayout,我们通过setContentView()设置的布局就会被添加到这个FrameLayout上。 DecorView中的布局关系如上图,我们看一下setContentView方法的代码。
public void setContentView(@LayoutRes int layoutResID) { getWindow().setContentView(layoutResID); initWindowDecorActionBar(); }首先它会设置FrameLayout的布局,之后回初始化ActionBar。看到这里我们就明白了,如果在setContentView方法之后设置requestWindowFeature()方法的话,由于已经初始化了ActionBar,所以并不会引起UI显示上的变化,必须在setContentView之前调用requestWindowFeature()方法才能在ActionBar初始化的时候影响它的显示。