Android中View绘制过程(三) setContentView()到performTraversals(),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; }
解释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(); } }
@Override public void requestFitSystemWindows() { checkThread(); mApplyInsetsRequested = true; scheduleTraversals(); }
final class TraversalRunnable implements Runnable { @Override public void run() { doTraversal(); } }
performTraversals()
performTraversals()中
使用performMeasure() 来测量View大小。
使用performLayout()来确定View的绘制区域。
使用performDraw()来真正的绘制。