簡介
- 問題
- LinearLayout的orientation屬性
- LinearLayout的layout_gravity屬性
- LinearLayout使用"orientation=horizontal/vertical",結(jié)合child view使用layout_gravity的各種情況的表現(xiàn)。
- 問題解答
問題:在使用LinearLayout的orientation=horizontal時(shí),使用layout_gravity="center"子布局只是縱向居中,并沒有橫向居中。
LinearLayout的orientation屬性
LinearLayout的布局方式有兩種,即由orientation屬性控制,默認(rèn)orientation=horizontal。在使用as作為開發(fā)工具的時(shí)候,如果在LinearLayout中出現(xiàn)多于兩個(gè)的同級子布局時(shí),as會強(qiáng)制要求設(shè)置顯示設(shè)置orientation屬性。
orientation屬性的值有兩個(gè):horizontal和vertical
分別表示橫向和縱向排列。
LinearLayout的layout_gravity屬性
layout_gravity屬性只有根布局是LinearLayout的情況下才能使用。表示子布局在父布局中的顯示方式。
layout_gravity有以下幾種值:
center:居中(橫向和縱向均居中)
center_horizontal:水平居中
center_vertical:垂直居中
以上都是常用的屬性,還有一些其他不常用的屬性,就不再贅述(clip_horizontal、clip_vertical、end、start、left、right…)。
LinearLayout使用"orientation=horizontal/vertical",結(jié)合child view使用layout_gravity的各種情況的表現(xiàn)。
兩種情況:
1、orientation=horizontal
子布局只能垂直方向的設(shè)置有效,不會水平方向的設(shè)置有效。
如果設(shè)置layout_gravity=center時(shí),只有垂直方向的設(shè)置有效,水平方向的設(shè)置無效。
2、orientation=vertical
子布局只能水平方向的設(shè)置有效,不會垂直方向的設(shè)置有效。
如果設(shè)置layout_gravity=center時(shí),只有水平方向的設(shè)置有效,垂直方向的設(shè)置無效。
解答
在查看LinearLayout的源碼的時(shí)候會發(fā)現(xiàn),LinearLayout在測量橫向和縱向的布局時(shí),有兩個(gè)方法分別為layoutVertical()和layoutHorizontal()分別用于測量橫向和縱向的布局位置。
我們就其中的一個(gè)方法進(jìn)行解釋:
layoutVertical():
void layoutVertical(int left, int top, int right, int bottom) {
/**
* 省略
*/
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;
}
final int layoutDirection = getLayoutDirection();
final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
case Gravity.CENTER_HORIZONTAL:
childLeft = paddingLeft + ((childSpace - childWidth) / 2)
+ lp.leftMargin - lp.rightMargin;
break;
case Gravity.RIGHT:
childLeft = childRight - childWidth - lp.rightMargin;
break;
case Gravity.LEFT:
default:
childLeft = paddingLeft + lp.leftMargin;
break;
}
if (hasDividerBeforeChildAt(i)) {
childTop += mDividerHeight;
}
childTop += lp.topMargin;
setChildFrame(child, childLeft, childTop + getLocationOffset(child),
childWidth, childHeight);
childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child);
i += getChildrenSkipCount(child, i);
}
}
}
在for循環(huán)中僅僅是判斷了CENTER_HORIZONTAL、RIGHT、LEFT三中情況,即在orientation=vertical時(shí),只有水平居中和居左和居右有效,因此這就是為什么我們在設(shè)置layout_gravity=center時(shí),只有水平方向的設(shè)置有效果了。
同理layoutHorizontal()方法也是同樣的設(shè)置。