【Android】View绘制过程分析之layout
来源:互联网 发布:java程序员转行 编辑:程序博客网 时间:2024/06/16 02:46
续前文“【Android】View绘制过程分析之measure”,继续分析View的绘制过程。
本文分析第2阶段,分析过程的注释标记在以下代码中。
/** * 此方法来给此View及它的子View分配大小和位置, * 子类不要覆写此方法,而覆写onLayout(boolean, int, int, int, int)方法即可 * 左上右下4个参数,表示此View相对于父View的位置 */public void layout(int l, int t, int r, int b) { int oldL = mLeft; int oldT = mTop; int oldB = mBottom; int oldR = mRight; boolean changed = isLayoutModeOptical(mParent) ? setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b); if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) { //我们通过这个方法来分配大小和位置 onLayout(changed, l, t, r, b); mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED; ListenerInfo li = mListenerInfo; if (li != null && li.mOnLayoutChangeListeners != null) { ArrayList<OnLayoutChangeListener> listenersCopy = (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone(); int numListeners = listenersCopy.size(); for (int i = 0; i < numListeners; ++i) { listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB); } } } mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;}/** * 此方法给子View分配大小和位置。 * 应该做的事情:遍历子View, 调用子View的layout(int, int, int,int)方法给子View分配大小和位置 * 左上右下4个参数,表示此View相对于父View的位置 */protected void onLayout(boolean changed, int left, int top, int right, int bottom) {}/** * View类中空实现这个方法,留给子类去实现。 * 下面看一下FrameLayout类的实现代码。 */protected void onLayout(boolean changed, int left, int top, int right, int bottom) { final int count = getChildCount(); /** * 下面4个方法: * 若不考虑padding,则以下4个值应为: * parentLeft = 0; parentRight = right-left; parentTop = 0; parentBottom = bottom - top; * 前面说到onLayout传入的左上右下4个参数是此View相对于父View的位置,那么right-left即求得此View所占的宽度,bottom-top即求得此View所点的高度 * 而这4个值构成的矩形范围,正是此View的占用范围 */ final int parentLeft = getPaddingLeftWithForeground(); final int parentRight = right - left - getPaddingRightWithForeground(); final int parentTop = getPaddingTopWithForeground(); final int parentBottom = bottom - top - getPaddingBottomWithForeground(); mForegroundBoundsChanged = true; //遍历子View,计算子View的位置 for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); //子View的大小在onMeasure(int, int)方法中已经计算得到 final int width = child.getMeasuredWidth(); final int height = child.getMeasuredHeight(); int childLeft; int childTop; int gravity = lp.gravity; if (gravity == -1) { gravity = DEFAULT_CHILD_GRAVITY; } final int layoutDirection = getLayoutDirection(); final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection); final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.LEFT: childLeft = parentLeft + lp.leftMargin; break; case Gravity.CENTER_HORIZONTAL: childLeft = parentLeft + (parentRight - parentLeft - width) / 2 + lp.leftMargin - lp.rightMargin; break; case Gravity.RIGHT: childLeft = parentRight - width - lp.rightMargin; break; default: childLeft = parentLeft + lp.leftMargin; } switch (verticalGravity) { case Gravity.TOP: childTop = parentTop + lp.topMargin; break; case Gravity.CENTER_VERTICAL: childTop = parentTop + (parentBottom - parentTop - height) / 2 + lp.topMargin - lp.bottomMargin; break; case Gravity.BOTTOM: childTop = parentBottom - height - lp.bottomMargin; break; default: childTop = parentTop + lp.topMargin; } //调用子View的layout(int,int,int,int), 上面计算得到的4个值确定了子View的位置范围 child.layout(childLeft, childTop, childLeft + width, childTop + height); } }}
@容新华技术博客 - http://blog.csdn.net/rongxinhua - 原创文章,转载请注明出处
0 0
- 【Android】View绘制过程分析之layout
- 【Android View绘制之旅】Layout过程
- View绘制之layout过程
- 【Android系列】View的绘制之layout过程
- 【Android】View绘制过程分析之measure
- 【Android】View绘制过程分析之draw
- Android View 绘制之Layout源码探索
- Android中View绘制流程:measure过程,layout过程
- View绘制详解,layout过程
- android学习9#--自定义View之绘制过程分析
- View的绘制流程分析之三 -- layout
- android中View绘制过程分析
- 【Android View绘制之旅】Measure过程
- 【Android View绘制之旅】Draw过程
- View绘制详解(四),谝一谝layout过程
- Android View绘制过程
- Android View绘制过程
- Android View绘制过程
- pat 1045
- 標量子查詢
- 1、去除上传图片功能中的浏览服务器按钮
- poj 1125 Stockbroker Grapevine
- EntityFramework 6.0< Code First > 连接 Mysql数据库
- 【Android】View绘制过程分析之layout
- appStore上传苹果应用程序软件发布流程
- poj 1502 MPI Maelstrom
- 【LVM】Insufficient Free Extents for a Logical Volume
- 计算机类部分核心期刊投稿经验
- cocos2dx lua 加载cocostudio 导出场景
- Xerces 序列化XML
- Delegate,Notification,KVO
- Getting Started with UML2