Android中View绘制过程(三) setContentView()到performTraversals()

来源:互联网 发布:软件项目报价表 编辑:程序博客网 时间:2024/06/07 00:11

Activity.java 调用最常用的SetContentView

public void setContentView(@LayoutRes int layoutResID) {        getWindow().setContentView(layoutResID);        initWindowDecorActionBar();    }
getWIndow()由之前的分析知道是PhoneWindow这个对象,

@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();        }        mContentParentExplicitlySet = true;    }

这段代码中的mContentParent,就是id为com.android.internal.R.id.content的FrameLayout,之后调用mLayoutInflater.inflate(layoutResID, mContentParent);

解释1 :Inflater简单来说就是将要inflate的View的属性(包括layout_width和layout_height)解析出来设置到View里,并将这个View添加到root这个ViewGroup的列表中。同时ViewGroup将自己设置为添加View的mParent。DecorView的mParent就是ViewRootImpl在setView的时候将自己view.assignParent(this);当做DecorView的mParent。

再之后调用mContentParent.requestApplyInsets();用于请求绘制。

经过几层调用之后进入到View.java

public void requestFitSystemWindows() {        if (mParent != null) {            mParent.requestFitSystemWindows();        }    }

最终会调用到ViewRootImpl中的。


@Override    public void requestFitSystemWindows() {        checkThread();        mApplyInsetsRequested = true;        scheduleTraversals();    }


final class TraversalRunnable implements Runnable {        @Override        public void run() {            doTraversal();        }    }

doTraversal()

performTraversals()


performTraversals()中

使用performMeasure() 来测量View大小。

使用performLayout()来确定View的绘制区域。

使用performDraw()来真正的绘制。

下一篇从performMeasure来学起。





原创粉丝点击