考虑以下简单的布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="top" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
</LinearLayout>
外部 LinearLayout
指定它有
android:gravity="bottom"
这意味着它希望自己的孩子“落到谷底”。
内部 LinearLayout
指定
android:layout_gravity="top"
这意味着它希望本身布局在其封闭布局的顶部。 (要指定android:layout_gravity
,必须直接编辑XML文件。似乎没有办法从Eclipse获取该属性。无论如何......)
Android如何解决这种冲突?上面的示例表明gravity
属性会覆盖layout_gravity
属性。一般来说冲突是如何解决的?
答案 0 :(得分:1)
通过查看LinearLayout
中的layoutVertical()
方法, gravity
本身的LinearLayout
决定孩子的定位方式
每个孩子的layout_gravity
仅用于布置&#34;在另一个方向&#34; (即左右)。
首先:
final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
final int minorGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
switch (majorGravity) {
case Gravity.BOTTOM:
childTop = ...
break;
// ... same for CENTER_VERTICAL and TOP
}
然后,为每个孩子:
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
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 = ...
break;
// ... same for RIGHT and LEFT
等同于layoutHorizontal()
。
此外,只是注释,但可以从Java代码访问android:layout_gravity
。它是LinearLayout.LayoutParams
类中的gravity
field(设置为子视图的LayoutParams
)。