android graphic(21)—view tree的创建过程
2016-04-08 14:31
1071 查看
view tree
view tree的构成
其中,各元素之间都有父子关系,这个父子关系在tree“遍历”的时候非常重要,从子到父,直到根节点(ViewRootImpl的performTraversals())。
ViewParent是继承tree中的一个关键接口,定义了作为一个View的parent的所有职责,View用来和其parent交互。
ViewGroup继承自View,实现了ViewParent。ViewRootImpl不算是一个View,因为没有继承View,但是实现了ViewParent接口,是该view tree的先祖,和window manager service做交互。
1.当Activity调用完setContentView后,其成员mWindow,即PhoneWindow中现存的View如下图所示,
其中,DecorView(父)mDecor是一个FrameLayout,一个ViewGroup,用来“盛放”其他的view组件,例如mContentParent(子),而mContentParent(父)也是一个ViewGroup,用来“盛放”mView(子)。
下面简要分析下上述过程,利用setContentView()添加用户自定义的mView时,
而decor.addView()和mContentParent.addView()最终会调用addViewInner(),在这里会去设置mDecor的子view、用户自定义view的父view为mContentParent。
2.在windowmanagerglobal的addView(decor)中,
所以经过上面的2步,最终形成的view tree如下图所示,从上到下依次是父子关系,而ViewRootImpl是祖先,用来和window manager service交互。
view tree的构成
view tree
下面这幅图是非常经典的view tree视图,其中叶子节点都是一个个实际的View,而ViewGroup作为View的容器,用来填充ViewGroup或者叶子节点View。其中,各元素之间都有父子关系,这个父子关系在tree“遍历”的时候非常重要,从子到父,直到根节点(ViewRootImpl的performTraversals())。
ViewParent是继承tree中的一个关键接口,定义了作为一个View的parent的所有职责,View用来和其parent交互。
/** ViewParent---- * Defines the responsibilities for a class that will be a parent of a View. * This is the API that a view sees when it wants to interact with its parent. * */
ViewGroup继承自View,实现了ViewParent。ViewRootImpl不算是一个View,因为没有继承View,但是实现了ViewParent接口,是该view tree的先祖,和window manager service做交互。
view tree的构成
下面分析一个view tree创建的过程,在/article/8286898.html中分析了activity申请surface的流程,其中主要包括:1.当Activity调用完setContentView后,其成员mWindow,即PhoneWindow中现存的View如下图所示,
其中,DecorView(父)mDecor是一个FrameLayout,一个ViewGroup,用来“盛放”其他的view组件,例如mContentParent(子),而mContentParent(父)也是一个ViewGroup,用来“盛放”mView(子)。
下面简要分析下上述过程,利用setContentView()添加用户自定义的mView时,
public void setContentView(View view, ViewGroup.LayoutParams params) { //① mContentParent开始肯定为空,首先执行 installDecor() if (mContentParent == null) { installDecor(); } else { mContentParent.removeAllViews(); } //②将用户自己的mView添加到mContentParent这个ViewGroup mContentParent.addView(view, params); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); } }
private void installDecor() { if (mDecor == null) { //创建DecorView mDecor mDecor = generateDecor(); } //创建mContentParent ,输入为其父view,mDecor if (mContentParent == null) { mContentParent = generateLayout(mDecor); } } protected ViewGroup generateLayout(DecorView decor) { View in = mLayoutInflater.inflate(layoutResource, null); //添加DecorView的子view decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); //contentParent 就是decor的子view ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT); } public View findViewById(int id) { return getDecorView().findViewById(id); }
而decor.addView()和mContentParent.addView()最终会调用addViewInner(),在这里会去设置mDecor的子view、用户自定义view的父view为mContentParent。
private void addViewInner(View child, int index, LayoutParams params, boolean preventRequestLayout) { // tell our children if (preventRequestLayout) { child.assignParent(this); } else { //自定义mView的mParent为mContentParent child.mParent = this; } onViewAdded(child); }
2.在windowmanagerglobal的addView(decor)中,
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) { //新建一个ViewRootImpl root = new ViewRootImpl(view.getContext(), display); view.setLayoutParams(wparams); mViews.add(view); mRoots.add(root); mParams.add(wparams); //将decor设置到ViewRootImpl中 root.setView(view, wparams, panelParentView); }
/** * We have one child */ public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { //将decor的父view设置为ViewRootImpl view.assignParent(this); } void assignParent(ViewParent parent) { if (mParent == null) { mParent = parent; } else if (parent == null) { mParent = null; } else { throw new RuntimeException("view " + this + " being added, but" + " it already has a parent"); } }
所以经过上面的2步,最终形成的view tree如下图所示,从上到下依次是父子关系,而ViewRootImpl是祖先,用来和window manager service交互。
相关文章推荐
- Android apk动态加载机制的研究(二):资源加载和activity生命周期管理
- Android开发——自动生成Android屏幕适配的dimens.xml文件
- 深入剖析Android的Volley库中的图片加载功能
- AndroidStudio - 手动更新gradle及关联项目详解
- JNI(深入理解Android卷I)的读书笔记
- Android使用Fragment打造万能页面切换框架(三)
- Android学习笔记:简易五子棋(上)
- Android使用Fragment打造万能页面切换框架(二)
- ArcGIS for Android地图控件的5大常见操作
- MTK6577+Android之按键(key)修改
- Android压缩图片到100K以下同时保持不失真
- Android使用Fragment打造万能页面切换框架(一)
- android快速实现毛玻璃效果
- Android 打开本地的手机软件市场评分
- Android 的线程跟线程池
- android drawable importer的使用
- Android Studio2.0以上反射$change属性问题
- Android 实现4MB以上大图片压缩不失真方法
- Android之Fragment(一)
- 关于android 图片加载优化