第一步:XML布局添加到DecorView的过程
我们都知道添加布局的方式,调用setContentView(R.layout.main)
Activity.java
public void setContentView(@LayoutRes int layoutResID) {
//向window中添加布局
getWindow().setContentView(layoutResID);
//初始化ActionBar
initWindowDecorActionBar();
}
向Window中添加布局
1.获取Window对象
Activity.java
private Window mWindow;
public Window getWindow() {
return mWindow;
}
/**
*
*使依附
*/
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
//这里初始化窗口对象
mWindow = new PhoneWindow(this);
}
2.PhoneWindows.setContentView(int)
PhoneWindow.java
@Override
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
3.XML解析其来解析XML内容
LayoutInflater.java
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
final Resources res = getContext().getResources();
if (DEBUG) {
Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
+ Integer.toHexString(resource) + ")");
}
//XML解析器解析
final XmlResourceParser parser = res.getLayout(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}
4.如何解析就不深究了
5.解析XML过程需要通过函数inflate传递一个参数对象root,该对象是一个ViewGroup
ViewGroup mContentParent;
初始化该对象mContentParent
PhoneWindow.java
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
}
}
/***/
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
protected ViewGroup generateLayout(DecorView decor) {
else {
// Embedded, so no decoration is needed.
layoutResource = R.layout.screen_simple;
// System.out.println("Simple!");
}
View in = mLayoutInflater.inflate(layoutResource, null);
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
mContentRoot = (ViewGroup) in;
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
return contentParent;
}
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
}
screen_simple.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<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" />
<!--这个就是ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);-->
<FrameLayout
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" />
</LinearLayout>