layout_gravity不起作用的原因分析
2015-08-06 16:11
363 查看
使用LinearLayout布局,其中的子View设置android:layout_gravity="bottom"属性后不起作用,原因是:
当LinearLayout设置android:orientation="vertical" 时, 只有水平方向的left,right,center_horizontal设置起作用,垂直方向的设置不起作用。
同样的:
当LinearLayout设置android:orientation="horizontal" 时, 只有垂直方向的top,bottom,center_vertical设置才起作用,水平方向的设置不起作用。
从View的绘制过程分析原因:
参考了View工作原理(四)view的layout过程/article/7965398.html
onlayout()方法:
[java] view
plaincopy
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (mOrientation == VERTICAL) {
layoutVertical();
} else {
layoutHorizontal();
}
}
LinearLayout有两种布局方法,垂直的和水平的,下面看垂直的布局源码
layoutVertical()方法源码:
[java] view
plaincopy
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);
}
}
}
当LinearLayout设置android:orientation="vertical" 时, 只有水平方向的left,right,center_horizontal设置起作用,垂直方向的设置不起作用。
同样的:
当LinearLayout设置android:orientation="horizontal" 时, 只有垂直方向的top,bottom,center_vertical设置才起作用,水平方向的设置不起作用。
从View的绘制过程分析原因:
参考了View工作原理(四)view的layout过程/article/7965398.html
onlayout()方法:
[java] view
plaincopy
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (mOrientation == VERTICAL) {
layoutVertical();
} else {
layoutHorizontal();
}
}
LinearLayout有两种布局方法,垂直的和水平的,下面看垂直的布局源码
layoutVertical()方法源码:
[java] view
plaincopy
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);
}
}
}
for循环是绘制子布局,switch语句是根据gravity的值确定水平方向的起始位置,三种值分别为:LEFT,CENTER_HORIZONTAL和RIGHT,由此可以看出只有水平方向的设置起作用。
相关文章推荐
- HTTP与HTTPS的区别
- hello World
- oracle导入时IMP-00010: 不是有效的导出文件, 头部验证失败
- CSS3选择器
- 利用JAVA反射机制实现调用私有方法
- hdoj---Rescue
- HTML5应用localStorage保存数据
- Android开发IM中的消息Notification的一个小小使用.
- MySql连接10060问题教训
- mysql 字段类型VARCHAR转换成DECIMAL
- elk 日志分析系统
- 生成 温度-AD 对照表
- IP地址CString和DWORD转换
- 线程安全与并发编程探究(七)--volatile java内存模型及线程知识小结
- 《鸟哥的Linux私房菜》学习Shell部分(2)
- ant 基础
- 【连载】实用小demo连载 3 —— js 时间转换 demo
- 使用excel进行数据挖掘(7)---- 从示例填充数据
- SIOCADDRT: No such process
- 8大网页设计新趋势(转载)