美文网首页陈大胖子学Android
Android高级UI之 从setContentView了解An

Android高级UI之 从setContentView了解An

作者: luffy之陈大胖子 | 来源:发表于2018-03-24 15:30 被阅读0次

    从setContentView了解Android UI绘制流程

    初学android的朋友可能会有这样一种疑问,为什么在setContentView方法里指定对应的layout资源,就能把对应的布局加载到屏幕上。那么,咱们现在就开始从源码来分析这样一个问题。

    首先,在onCreate方法里面,调用了setContentView方法,这个方法是来自Activity的。我们进入到Activity的源码:
    public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
    }

    这里调用了getWindow的setContentView方法,那getWindow返回了一个Window对象,而Window是一个抽象类,它的唯一子类叫做PhoneWindow,那么这个window是什么时候被赋值的呢?是在attach里面直接new出来的
    mWindow = new PhoneWindow(this, window, activityConfigCallback)

    我们进入到PhoneWindow看一下setContentView方法。

    这个方法主要做了两件事:
    1.installDecor
    installDecor这个方法干了两件事
    1.1 generateDecor
    这里实例化了一个DecorView ,DecorView继承自FrameLayout,用来装载我们的页面布局
    1.2 generateLayout
    如果没有特殊情况的话,是将R.layout.screen_simple这样一个布局加载到DecorView中
    布局文件如下:是一个纵向布局 ViewStup用于摆放action bar,而FrameLayout用于摆放我们布局文件中的布局

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

    这一步骤完成之后,mContentParent就不为null了,mContentParent实际上是一个ViewGroup,它对应的类型是R.id.content,在R.layout.screen_simple中对应的实际上就是一个FrameLayout。
    2.将setContentView传入的layout解析并绘制
    主要代码就是 mLayoutInflater.inflate(layoutResID, mContentParent);

    我们来看一下这个方法:
    
    final XmlResourceParser parser = res.getLayout(resource);
    try {
            return inflate(parser, root, attachToRoot);
    } finally {
            parser.close();
    }
    这个方法最终返回一个View,也就是向mContentParent中添加子View。
    主要代码 :
        View temp = createViewFromTag(root, name, inflaterContext, attrs);
        temp.setLayoutParams(params);
        rInflateChildren(parser, temp, attrs, true);
        root.addView(temp, params);
    

    其中涉及到的xml解析可见下图


    LayoutInflater.png

    这样,我们整个布局就加载到了对应的Activity当中了,那么,布局是什么时候开始绘制,如何绘制到屏幕上的呢?请看下回分解。

    总结:最终Activity的层次结构可以总结为下图:


    activity.jpg

    相关文章

      网友评论

        本文标题:Android高级UI之 从setContentView了解An

        本文链接:https://www.haomeiwen.com/subject/xnvqcftx.html