Android View
来源:互联网 发布:策略游戏 知乎 编辑:程序博客网 时间:2024/06/17 05:29
Layout起布局作用,确定View的位置。当ViewGroup确定位置后,会遍历子View并调用其layout方法确定子View的位置。
View的onLayout方法
View的onLayout方法是一个空实现,因为子View不包含其他View,不需要被调用。
ViewGroup的onLayout方法
ViewGroup会先调用layout方法:
public final void layout(int l, int t, int r, int b) { boolean changed = setFrame(l, t, r, b); if (changed || (mPrivateFlags & LAYOUT_REQUIRED) == LAYOUT_REQUIRED) { if (ViewDebug.TRACE_HIERARCHY) { ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_LAYOUT); } onLayout(changed, l, t, r, b); mPrivateFlags &= ~LAYOUT_REQUIRED; } mPrivateFlags &= ~FORCE_LAYOUT; }
ViewGroup的onLayout方法是一个抽象方法,由子类去实现,主要是让ViewGroup在这个方法确定每个子View的位置。
@Override protected abstract void onLayout(boolean changed, int l, int t, int r, int b);
我们需要关心的其实就是这个方法,以LinearLayout为例:
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (mOrientation == VERTICAL) { layoutVertical(); } else { layoutHorizontal(); } }
根据android:orientation属性给子View设置不同的位置,看layoutVertical方法代码:
void layoutVertical() { final int paddingLeft = mPaddingLeft; int childTop = mPaddingTop; int childLeft; // Where right end of child should go final int width = mRight - mLeft; int childRight = width - mPaddingRight; // Space available for child int childSpace = width - paddingLeft - mPaddingRight; final int count = getVirtualChildCount(); final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK; final int minorGravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK; if (majorGravity != Gravity.TOP) { switch (majorGravity) { case Gravity.BOTTOM: // mTotalLength contains the padding already, we add the top // padding to compensate childTop = mBottom - mTop + mPaddingTop - mTotalLength; break; case Gravity.CENTER_VERTICAL: childTop += ((mBottom - mTop) - mTotalLength) / 2; break; } } for (int i = 0; i < count; i++) { final View child = getVirtualChildAt(i); if (child == null) { childTop += measureNullChild(i); } else if (child.getVisibility() != GONE) { final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams(); int gravity = lp.gravity; if (gravity < 0) { gravity = minorGravity; } switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.LEFT: childLeft = paddingLeft + lp.leftMargin; break; case Gravity.CENTER_HORIZONTAL: childLeft = paddingLeft + ((childSpace - childWidth) / 2) + lp.leftMargin - lp.rightMargin; break; case Gravity.RIGHT: childLeft = childRight - childWidth - lp.rightMargin; break; default: childLeft = paddingLeft; break; } childTop += lp.topMargin; setChildFrame(child, childLeft, childTop + getLocationOffset(child), childWidth, childHeight); childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child); i += getChildrenSkipCount(child, i); } } }
在layout时,会用到子View测量后的值,所以先测量,后布局。最后调用setChildFrame方法:
private void setChildFrame(View child, int left, int top, int width, int height) { child.layout(left, top, left + width, top + height);}
调用子View的layout方法确定位置。
我们自定义流式布局时,就需要像这样重写onLayout方法。
阅读全文
0 0
- android.view.View
- android.view.View---中文
- android.view.View
- android.view.View 相关
- android.view.view
- 有关android.view.View
- Android View---自定义View
- Android View---自定义View
- android.view.View.getImportantForAccessibility()
- android View
- android View
- android View
- Android View
- Android-View
- android-view
- android view
- android view
- Android: View
- CentOS 6.5/6.6 安装(install)mysql 5.7
- Markdown入门详解
- 大端模式 小端模式
- Groovy书写不依赖与实体的GORM
- tmux用法
- Android View
- hdu1828-Picture 线段树+扫描线 求周长并
- Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法
- HTML课堂讲义(5)
- Win7系统搭建FTP服务器
- Linux命令行终端提示符实用技巧
- 服务机器人让你拥抱智慧生活
- Mapper 文件编写技巧
- hadoop2 (2017-7-21修改)对SequeneceFile 的(读写)操作