使用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()方法:
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- if (mOrientation == VERTICAL) {
- layoutVertical();
- } else {
- layoutHorizontal();
- }
- }
LinearLayout有两种布局方法,垂直的和水平的,下面看垂直的布局源码
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);
- }
- }
- }
for循环是绘制子布局,switch语句是根据gravity的值确定水平方向的起始位置,三种值分别为:LEFT,CENTER_HORIZONTAL和RIGHT,由此可以看出只有水平方向的设置起作用。