Android窗口
先来了解下Android系统的窗口布局。当我们设置窗口的Theme为可见样式时,Android的窗口如下图:
查看Activity的源码,Activity中有一个私有成员Window(mWindow),而Window是一个抽象类,它提供了绘制窗口的一组通用API(如下第一段代码);PhoneWindow继承自Window,是Window的具体实现类;PhoneWindow中有一个私有成员DecorView;DecorView对象是所有应用窗口(Activity界面)的根View(如下第二段代码),DecorView继承自FrameLayout,在内部根据用户设置的Activity主题对FrameLayout进行修饰,为用户提供给定Theme下的布局样式。如上图所示,一般情况下,DecorView中包含一个用于显示Activity标题的TitleView和一个用于显示内容的ContentView。
(1)Window类,是一个抽象类,提供了绘制窗口的一组通用API。可以将之理解为一个载体,各种view在这个载体上显示,源码如下:
/**
* Abstract base class for a top-level window look and behavior policy. An
* instance of this class should be used as the top-level view added to the
* window manager. It provides standard UI policies such as a background, title
* area, default key processing, etc.
*
* <p>The only existing implementation of this abstract class is
* android.view.PhoneWindow, which you should instantiate when needing a
* Window.
*/
public abstract class Window {
//...
//指定Activity窗口的风格类型
public static final int FEATURE_NO_TITLE = 1;
public static final int FEATURE_INDETERMINATE_PROGRESS = 5;
//设置布局文件
public abstract void setContentView(int layoutResID);
public abstract void setContentView(View view);
//请求指定Activity窗口的风格类型
public boolean requestFeature(int featureId) {
final int flag = 1<<featureId;
mFeatures |= flag;
mLocalFeatures |= mContainer != null ? (flag&~mContainer.mFeatures) : flag;
return (mFeatures&flag) != 0;
}
//...
}
(2)PhoneWindow类继承自Window,是Window的具体实现类,即我们可以通过该类具体去绘制窗口。PhoneWindow有一个私有成员DecorView,DecorView对象是所有应用窗口(Activity界面)的根View。简而言之,PhoneWindow类是把一个FrameLayout类,即DecorView对象进行一定的包装,将它作为应用窗口的根View,并提供一组通用的API。
public class PhoneWindow extends Window implements MenuBuilder.Callback {
//...
private DecorView mDecor; //该对象是所有应用窗口的根视图,是FrameLayout的子类
//该对象是Activity布局文件的父视图,一般来说是一个FrameLayout型的ViewGroup
//同时也是DecorView对象的一个子视图
private ViewGroup mContentParent;
//设置标题
@Override
public void setTitle(CharSequence title) {
if (mTitleView != null) {
mTitleView.setText(title);
}
mTitle = title;
}
//设置背景图片
@Override
public final void setBackgroundDrawable(Drawable drawable) {
if (drawable != mBackgroundDrawable || mBackgroundResource != 0) {
mBackgroundResource = 0;
mBackgroundDrawable = drawable;
if (mDecor != null) {
mDecor.setWindowBackground(drawable);
}
}
}
//...
}
(3)DecorView类,是FrameLayout的子类,是所有应用窗口的根View。
DecorView初始化时加载R.layout.screen_title布局文件,位于frameworks/base/core/res/layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:fitsSystemWindows="true">
<!-- Popout bar for action modes -->
<ViewStub android:id="@+id/action_mode_bar_stub"
android:inflatedId="@+id/action_mode_bar"
android:layout="@layout/action_mode_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/actionBarTheme" />
<FrameLayout
android:l