Android View绘制(一)- LayoutInflater.inflate() 流程简要解析

Android View绘制- LayoutInflater.inflate() 流程简要解析

布局,作为 Android 中展示 UI 的最主要的元素,其实它是怎么通过布局文件转化为实际的 UI 的?这篇文章,就是对这一过程进行简要的解析,并且提出一些实际开发过程需要注意的问题。

阅读该文章你可以了解到

  1. LayoutInfalter 的工作过程
  2. 布局优化的一些建议

LayoutInflater 原理讲解

我们需要在 Activity 上显示一个布局文件,通常在 Activity 的 onCreate() 使用以下代码:

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_inner_class_memory_leack);
}

实际上, setContentView() 的调用链如下

// Activity.setContentView(),这里的getWindow() 拿到的是一个 PhoneWindow 对象
public void setContentView(@LayoutRes int layoutResID) {
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}
// PhoneWinwod.setContent()
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();
        }
        mContentParentExplicitlySet = true;
 }

最终会进入到 PhoneWindow 这里,然后最终调用的代码是第二十二行的 mLayoutInflater.inflate(layoutResID, mContentParent); 这一行代码,这里将 mContentParent 传入作为父容器。然后最终都会调用到 LayoutInflater 的 inflate() 方法,如下:

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
    synchronized (mConstructorArgs) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");

        final Context inflaterContext = mContext;
        final AttributeSet attrs = Xml.asAttributeSet(parser);
        Context lastContext = (Context) mConstructorArgs[0];
        mConstructorArgs[0] = inflaterContext;
        View result = root;//注意该方法的返回值

        try {
            // Look for the root node.
            int type;
            while ((type = parser.next()) != XmlPullParser.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值