Android UI树的Layout原理
来源:互联网 发布:电脑管家数据恢复收费? 编辑:程序博客网 时间:2024/06/03 17:27
在UI树的任意一个节点,当它被它的父亲layout时,这个节点的layout方法被父亲调用:
public void layout(int l, int t, int r, int b) { if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) { onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec); mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT; } 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; mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;}
我们可以看到,调用setFrame方法将新的坐标和宽高设置进去,在setFrame中还有一个工作就是:当size发生变化时,保存PFLAG_DRAWN位,invalidate这个View,然后恢复PFLAG_DRAWN位
然后,接下来就是onLayout方法,当前View如果不是ViewGroup,那么onLayout里面为空,什么都不做,当前View如果是ViewGroup,那么会调用每一个孩子进行layout
举FrameLayout的onLayout方法为例
void layoutChildren(int left, int top, int right, int bottom, boolean forceLeftGravity) { final int count = getChildCount(); final int parentLeft = getPaddingLeftWithForeground(); final int parentRight = right - left - getPaddingRightWithForeground(); final int parentTop = getPaddingTopWithForeground(); final int parentBottom = bottom - top - getPaddingBottomWithForeground(); mForegroundBoundsChanged = true; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 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.CENTER_HORIZONTAL: childLeft = parentLeft + (parentRight - parentLeft - width) / 2 + lp.leftMargin - lp.rightMargin; break; case Gravity.RIGHT: if (!forceLeftGravity) { childLeft = parentRight - width - lp.rightMargin; break; } case Gravity.LEFT: 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; } child.layout(childLeft, childTop, childLeft + width, childTop + height); } }}
总结成一句话就是:对每一个孩子,取出LayoutParams,计算left和top,然后调用child.layout方法。
0 0
- Android UI树的Layout原理
- Android : UI Layout
- Android UI树的measure原理
- [Android Develop_002]-Android UI Layout
- Android UI Layout 之 AbsoluteLayout
- Android UI Layout 之 AbsoluteLayout
- Android基本之UI Layout
- android UI-Layout界面布局
- Android UI 优化 [ 类别:Layout ] <merge>的学习
- AndroidStudio官方的Android 使用 Layout Editor 构建 UI
- Android UI之Android Layout XML属性
- android-View工作原理(四)view的layout过程
- android-View工作原理(四)view的layout过程
- Android UI 之 layout(一)初探layout
- Android之UI显示的原理分析
- Android UI 优化 [ 类别:Layout ] #1
- Android UI 优化 [ 类别:Layout ] #2
- Android UI 优化 [ 类别:Layout ] #3
- NAT的四种类型及检测[转]
- 我的阿里巴巴offer之路
- opengl之vsh、fsh简易介绍+cocos2dx 3.0 shader 变灰
- PowerDesigner(九)-模型文档编辑器(生成项目文档)
- Java的Abstraction抽象类/方法-笔记
- Android UI树的Layout原理
- hdu3746 Cyclic Nacklace(KMP)
- 创建并使用静态库(ar 命令)
- for(int i = 0; i < 10; i++)和ctrl z在VC++6.0和VS2005中的不同表现
- string 构造函数 java
- CString/string 区别及其转化
- 最大子序列问题
- 基于连通图的分裂聚类算法
- laravel相关网址