setContentView(xml) 加载布局可以看出,activity, window, view 之间的关系
继承Activity时使用:
requestWindowFeature(Window.FEATURE_NO_TITLE)
继承AppCompatActivity时使用,对继承Activity的无效:
supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
注意:设置WindowFeature 时需要在setContentView之前,因为在添加布局文件到DecorView上时需要使用这个样式
继承 AppCompatActivity
1. AppCompatDelegate.create
初始化 2步骤
2. AppCompatDelegateImpl
3. ensureSubDecor();
4. ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
// 渲染布局 到 contentParent
5. LayoutInflater.from(mContext).inflate(resId, contentParent);
步骤3. ensureSubDecor 创建
createSubDecor
--> ensureWindow //在AppCompatActivity的onCreate时,创建window 并且检查window
--> mWindow.getDecorView() //获取Window(PhoneWindow) 中的DecorView
--> installDecor //PhoneWindow中的getDecorView 方法调用的,做了如下两件事:
--> 1.generateDecor //new DecorView(x, x, x, x()) 直接 new DecorView 返回
--> 2. generateLayout // 获取 mContentParent,设置状态栏、窗口样式、导航栏颜色、获取布局
--> mDecor.onResourcesLoaded(mLayoutInflater, layoutResource) // 设置界面布局,
将 mLayoutInflater布局加入到 layoutResource 中 的控件Id 为R.id.content
// 也是为什么出现 subDecor
//获取 继承 Activity
--> ViewGroup windowContentView = (ViewGroup)mWindow.findViewById(android.R.id.content);
--> windowContentView.setId(View.NO_ID); //将原始Id 置为空
// 将R.id.action_bar_activity_content ID 修改为 R.id.content
contentView.setId(android.R.id.content);
--> mWindow.setContentView(subDecor); // 设置 subDecor
这就完成了 setContentView 加入布局的流程
步骤5: 创建View 的流程
//先创建RootView(也就是布局的根View)
View temp = createViewFromTag(root, name, inflaterContext, attrs);
--> if (-1 == name.indexOf('.')) {
//系统的View
view = onCreateView(context, parent, name, attrs);
--> PhoneLayoutInflater.createView(name, attrs)
//prefix 前缀
"android.widget.",
"android.webkit.",
"android.app.",
"android.view.",
--> View view = createView(name, prefix, attrs)
} else {
//自定义的View
view = createView(context, name, null, attrs);
}
//以上两种创建View, 都会回到 这里使用反射获取全路径控价
1. clazz = Class.forName(prefix != null ? (prefix + name) : name, false,
mContext.getClassLoader()).asSubclass(View.class);
//获取控件后,就拿构造对象
2. constructor = clazz.getConstructor(mConstructorSignature);
//创建控件
3. View view = constructor.newInstance(args);
继承 Activity
getWindow().setContentView //调用的是 PhonwWindow 的setContentView
--> installDecor // 直接就和 AppCompatActivity 的 步骤3. ensureSubDecor 创建一样
--> mLayoutInflater.inflate(layoutResID, mContentParent);// 渲染布局 到 mContentParent