android外部文件初始化布局,setContentView() 初始化

一、初始化布局

窗体是视图的容器,手机平台窗体是 PhoneWindow 类。

在 package com.android.internal.policy 包中,定义 /** @hide */ DecorView 类,树结构的根视图类型,继承 FrameLayout 类。

在 Activity 类的 attach() 方法,初始化内部 mWindow,即创建 PhoneWindow 对象。

public PhoneWindow(Context context) {

super(context);

mLayoutInflater = LayoutInflater.from(context);

}

创建布局解析器 LayoutInflater 类。

在 Activity 类的 onCreate() 方法,通常 setContentView() 方法 设置布局文件,资源 id 是 R.layout.xxx。

public void setContentView(@LayoutRes int layoutResID) {

getWindow().setContentView(layoutResID);

initWindowDecorActionBar();

}

调用 Window 的 setContentView() 方法。

private DecorView mDecor;//根View

private ViewGroup mContentParent;//存放解析出外部的View

private ViewGroup mContentRoot;//mDecor的直接子View

@Override

public void setContentView(int layoutResID) {

if (mContentParent == null) {

//初始化mDecor,创建mContentRoot和mContentParent

installDecor();

} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

mContentParent.removeAllViews();

}

if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

...

} else {

//解析资源ID的View加入到mContentParent的子View中去

mLayoutInflater.inflate(layoutResID, mContentParent);

}

mContentParent.requestApplyInsets();

final Callback cb = getCallback();

if (cb != null && !isDestroyed()) {

cb.onContentChanged();

}

}

Window 内部 包含 DecorView。

installDecor() 方法,初始化 DecorView,创建 mContentRoot 和 mContentParent

mContentRoot 是 inflate() xml 文件的视图,添加到顶层视图。

//PhoneWindow的generateLayout方法。mContentRoot创建的代码段。

View in = mLayoutInflater.inflate(layoutResource, null);

//加入顶层视图。

decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));

mContentRoot = (ViewGroup) in;

系统框架根据 Window 不同 Feature ,选择不同的 layoutResource 布局资源解析,将解析 View 添加到 DecorView 子视图。

举例一种最简单 screen_simple.xml 文件。

android:layout_width="match_parent"

android:layout_height="match_parent"

android:fitsSystemWindows="true"

android:orientation="vertical">

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" />

android:id="@android:id/content"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:foregroundInsidePadding="false"

android:foregroundGravity="fill_horizontal|top"

android:foreground="?android:attr/windowContentOverlay" />

mContentParent 视图,通过 findViewById() 方法。

解析资源 id 节点 com.android.internal.R.id.content,FrameLayout 类型。

ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);

56211ce6f250

树形结构视图

二、XML 解析

LayoutInflater 类,解析 xml 类型 layout 布局文件。

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {

return inflate(resource, root, root != null);

}

根据 int 类型的 resource,生成一个 XmlResourceParser 对象。

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {

synchronized (mConstructorArgs) {

final Context inflaterContext = mContext;

final AttributeSet attrs = Xml.asAttributeSet(parser);

mConstructorArgs[0] = inflaterContext;

View result = root;

try {

int type;

while ((type = parser.next()) != XmlPullParser.START_TAG &&

type != XmlPullParser.END_DOCUMENT) {

// Empty

}

final String name = parser.getName();

if (TAG_MERGE.equals(name)) {

...

} else {

final View temp = createViewFromTag(root, name, inflaterContext, attrs);

ViewGroup.LayoutParams params = null;

if (root != null) {

params = root.generateLayoutParams(attrs);

if (!attachToRoot) {

temp.setLayoutParams(params);

}

}

if (root != null && attachToRoot) {

root.addView(temp, params);

}

if (root == null || !attachToRoot) {

result = temp;

}

}

} catch (XmlPullParserException e) {

} catch (Exception e) {

} finally {

}

return result;

}

}

XmlPullParser 负责解析 xml 文件,根据 Tag 生成 View 对象。

addView() 方法,将生成的视图添加到 root ,即 mContentParent 视图。

三、总结

DecorView 类,树结构顶层视图类。

mContentRoot 视图,根据 Android_SDK 资源布局 xml 文件解析的视图。

mContentParent ,FrameLayout 类型,mContentRoot 的一个子视图,装载 setContentView() 方法 资源 layout id 视图布局,该视图还包含其他子视图,例如 ActionBar,装载到 ViewStub 节点。

setContentView() 方法,负责 layout 初始化,实现树视图结构,未进行视图测量、布局和绘制。

任重而道远

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值