gravity和layout_gravity
xx
目次
背景 #
从开始写Android不断地有人告诉我,用gravity和layout_gravity控制View的位置,总是不明白两者有什么差别(中途明白过,又忘了😭),又是怎么实现的,最近想起来,赶紧查一查。
实现 #
首先gravity和layout_gravity都是View的一个属性,一直以为(没错,又是以为)类似height和width类似的,每个View都会有的,其实细想一下不是每个View都有。
gravity #
TextView是有gravity的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| // 解析属性
...
case com.android.internal.R.styleable.TextView_gravity:
setGravity(a.getInt(attr, -1));
...
// 赋值
public void setGravity(int gravity) {
...
mGravity = gravity;
...
}
// mGravity定义及默认值
private int mGravity = Gravity.TOP | Gravity.START;
// View中能起作用一定是跟测量有关,找到相关代码
public int getExtendedPaddingTop() {
...
final int gravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
if (gravity == Gravity.TOP) {
return top;
} else if (gravity == Gravity.BOTTOM) {
return top + viewht - layoutht;
} else { // (gravity == Gravity.CENTER_VERTICAL)
return top + (viewht - layoutht) / 2;
}
...
}
|
layout_gravity #
layout_gravity哪有呢,LinearLayout:
1
| gravity = a.getInt(com.android.internal.R.styleable.LinearLayout_Layout_layout_gravity, -1);
|
LinearLayout中布局子View的代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| void layoutVertical(int left, int top, int right, int bottom) {
...
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;
}
...
}
|
恰好LinearLayout中也有用到gravity
1
2
3
4
5
| // 取到gravity
index = a.getInt(com.android.internal.R.styleable.LinearLayout_gravity, -1);
if (index >= 0) {
setGravity(index);
}
|
在设置baselineAligned为true时,gravity才会发挥作用。
Gravity #
Standard constants and tools for placing an object within a potentially larger container.
上面是源码中官方的注释。
可以发现代码中设置Gravity的地方用到了Gravity类,比较好理解Gravity类就是官方提供的一个工具类,让Gravity中每个属性代表的值统一。
总结 #
- gravity和layout_gravity和那个View没有关系,你想自定义View的时候实现也可以用;
- gravity是控制View内部的内容从哪里开始放置,一般用在View上;
- layout_gravity是控制子View怎么布局,一般用在ViewGroup上;
- 只要你想怎么实现都行。