解决android:gravity和android:layout_gravity之间的冲突

时间:2014-07-18 13:51:51

标签: android android-layout android-linearlayout

考虑以下简单的布局。

<?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属性。一般来说冲突是如何解决的?

1 个答案:

答案 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)。