理解为什么requestWindowFeature一定要放在setContentView的前面
一、Android的UI结构
我们知道,View是Android UI最基础的组件,而对于一个Android手机而言,最根部、充满了整个手机屏幕的那个View被称为DecorView,DecorView是整个View Tree的跟结点,他有两个子结点,一个是TitleView,从名字上可以看出来,这个View对应于Activity中的ActionBar或者Toolbar。另一个子节点是ContentView,他对于与ActionBar的下面,负责展示主要的界面。
二、ContentView和setContentView
ContentView 是一个FrameLayout。
public void setContentView (int layoutResID)
Added in API level 1
Set the activity content from a layout resource. The resource will be inflated, adding all top-level views to the activity.
setContentView传入了一个layout文件,首先将这个layout渲染成View,然后添加到ContentView里面。
/**
* 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();
}
然而通过阅读源码可以发现,在这之后还调用了initWindowDecorActionBar(),继续跟进:
/**
* Creates a new ActionBar, locates the inflated ActionBarView,
* initializes the ActionBar with the view, and sets mActionBar.
*/
private void initWindowDecorActionBar() {
Window window = getWindow();
// Initializing the window decor can change window feature flags.
// Make sure that we have the correct set before performing the test below.
window.getDecorView();
if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) {
return;
}
mActionBar = new WindowDecorActionBar(this);
mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
mWindow.setDefaultIcon(mActivityInfo.getIconResource());
mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
}
这里,如果在合理的场景下,会new一个ActionBar出来添加到DecorView上,并且初始化了Actionbar的图标。
通过以上分析,可以初步理解为,在执行过setContentView之后,ActionBar已经完成了初始化,因此之后再调用
requestWindowFeature(Window.FEATURE_NO_TITLE);
可能为时已晚。
浙公网安备 33010602011771号