requestWindowFeature 的用法往往出现在设置布局前,setContentView方法前的,这是重点一定要注意他必须放在setContentView 方法前、
我们可以从源码来解释下,requestWindows 方法其实走的是requestFeature 路线
@Override
public boolean requestFeature(int featureId) {
if (mContentParent != null) {
throw new AndroidRuntimeException("requestFeature() must be called before adding content");
}
.....
return super.requestFeature(featureId);
}
但是在activity中使用setContentView()时,实际上走的是phonewindow的setContentView,根据代码我们看到
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {if (mContentParent == null) {
installDecor();
} else {
mContentParent.removeAllViews();
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
它会首先判断mContentParent 是否为null,如果为null,进入installDecor();
private void installDecor() {
......
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
mTitleView = (TextView)findViewById(com.android.internal.R.id.title);
if (mTitleView != null) {
if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
View titleContainer = findViewById(com.android.internal.R.id.title_container);
if (titleContainer != null) {
titleContainer.setVisibility(View.GONE);
} else {
mTitleView.setVisibility(View.GONE);
}
if (mContentParent instanceof FrameLayout) {
((FrameLayout)mContentParent).setForeground(null);
}
} else {
mTitleView.setText(mTitle);
}
}
.....
}
这是installDecor方法的部分代码,从中我们可以看到,它会对mContentParent 进行初始化,从而赋予相应的值,这就是RequestWindowFeature为啥一定要在setContentView之前调用就会抛此类异常
然后我们看下用法:
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:标题栏右侧的图标
二、详解
默认显示状态
1.FEATURE_CUSTOM_TITLE详解
- this.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
- setContentView(R.layout.main);
这是因为没有设置Featrue
在上面代码后加:getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
自定义标题完成,它是一个xml文件布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleSmallTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" >
</ProgressBar>
</LinearLayout>
2.FEATURE_INDETERMINATE_PROGRESS详解
可以用来表示一个进程正在运行
- this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- setContentView(R.layout.main);
- getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, R.layout.progress);
- setProgressBarIndeterminateVisibility(true);
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
- <ProgressBar
- android:id="@+id/progress"
- style="?android:attr/progressBarStyleSmallTitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical" >
- </ProgressBar>
- </LinearLayout>
3.FEATURE_LEFT_ICON和FEATURE_RIGHT_ICON详解
- requestWindowFeature(Window.FEATURE_RIGHT_ICON);
- setContentView(R.layout.main);
- getWindow().setFeatureDrawableResource(Window.FEATURE_RIGHT_ICON,R.drawable.ic_launcher);
- requestWindowFeature(Window.FEATURE_LEFT_ICON);
- setContentView(R.layout.main);
- getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,R.drawable.ic_launcher);
4.FEATURE_NO_TITLE详解
- this.requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.main);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);