layout_gravity不起作用的原因分析

本文详细解析了LinearLayout布局中子View的android:layout_gravity属性在不同方向上的表现,并通过源码解释了为何某些方向的gravity设置不起作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用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过程http://blog.youkuaiyun.com/ff20081528/article/details/17784911

onlayout()方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2.    protected void onLayout(boolean changed, int l, int t, int r, int b) {  
  3.        if (mOrientation == VERTICAL) {  
  4.            layoutVertical();  
  5.        } else {  
  6.            layoutHorizontal();  
  7.        }  
  8.    }  

LinearLayout有两种布局方法,垂直的和水平的,下面看垂直的布局源码

layoutVertical()方法源码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void layoutVertical() {  
  2.         final int paddingLeft = mPaddingLeft;  
  3.         int childTop = mPaddingTop;  
  4.         int childLeft;  
  5.         // Where right end of child should go  
  6.         final int width = mRight - mLeft;  
  7.         int childRight = width - mPaddingRight;  
  8.         // Space available for child  
  9.         int childSpace = width - paddingLeft - mPaddingRight;  
  10.         final int count = getVirtualChildCount();  
  11.         final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;  
  12.         final int minorGravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;  
  13.         if (majorGravity != Gravity.TOP) {  
  14.            switch (majorGravity) {  
  15.                case Gravity.BOTTOM:  
  16.                    // mTotalLength contains the padding already, we add the top  
  17.                    // padding to compensate  
  18.                    childTop = mBottom - mTop + mPaddingTop - mTotalLength;  
  19.                    break;  
  20.                case Gravity.CENTER_VERTICAL:  
  21.                    childTop += ((mBottom - mTop)  - mTotalLength) / 2;  
  22.                    break;  
  23.            }  
  24.         }  
  25.         for (int i = 0; i < count; i++) {  
  26.             final View child = getVirtualChildAt(i);  
  27.             if (child == null) {  
  28.                 childTop += measureNullChild(i);  
  29.             } else if (child.getVisibility() != GONE) {  
  30.                 final int childWidth = child.getMeasuredWidth();  
  31.                 final int childHeight = child.getMeasuredHeight();  
  32.                 final LinearLayout.LayoutParams lp =  
  33.                         (LinearLayout.LayoutParams) child.getLayoutParams();  
  34.                 int gravity = lp.gravity;  
  35.                 if (gravity < 0) {  
  36.                     gravity = minorGravity;  
  37.                 }  
  38.                 switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {  
  39.                     case Gravity.LEFT:  
  40.                         childLeft = paddingLeft + lp.leftMargin;  
  41.                         break;  
  42.                     case Gravity.CENTER_HORIZONTAL:  
  43.                         childLeft = paddingLeft + ((childSpace - childWidth) / 2)  
  44.                                 + lp.leftMargin - lp.rightMargin;  
  45.                         break;  
  46.                     case Gravity.RIGHT:  
  47.                         childLeft = childRight - childWidth - lp.rightMargin;  
  48.                         break;  
  49.                     default:  
  50.                         childLeft = paddingLeft;  
  51.                         break;  
  52.                 }  
  53.                 childTop += lp.topMargin;  
  54.                 setChildFrame(child, childLeft, childTop + getLocationOffset(child),  
  55.                         childWidth, childHeight);  
  56.                 childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child);  
  57.                 i += getChildrenSkipCount(child, i);  
  58.             }  
  59.         }  
  60.     }  
for循环是绘制子布局,switch语句是根据gravity的值确定水平方向的起始位置,三种值分别为:LEFT,CENTER_HORIZONTAL和RIGHT,由此可以看出只有水平方向的设置起作用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值