安卓中gravity和layout_gravity有什么区别?

1459
我知道我们可以将以下值设置为android:gravityandroid:layout_gravity属性:
  1. center
  2. center_vertical
  3. center_horizontal等。
但我对这两个属性的使用感到困惑。 android:gravityandroid:layout_gravity之间有什么区别?

293
记忆技巧:将"layout-gravity"看作"布局外的重力"。 - Vishnu Haridas
7
居中 == 垂直居中 | 水平居中 - Yousha Aleayoub
5
这些视频帮助我很多地理解了它们的不同之处:https://www.youtube.com/watch?v=DxfYeAUd238,https://www.youtube.com/watch?v=1FyAIWLVcTc。 - Roni Castro
“ImageView”的行为似乎与“TextView”的不同。 - samus
22个回答

1458

它们的名称应该能帮助您:

  • android:gravity 设置视图(即其子视图)内容的重力。
  • android:layout_gravity 设置视图或布局相对于其父级的重力。

这里有一个例子 (链接).


103
基本上,所有带有"layout_"前缀的东西都定义了影响元素外部的某些内容。 - Triang3l
38
如果只看名称,我觉得这很有趣。每次我都认为"layout_gravity"的意思是"这个ViewGroup布局其内容的重力",而"gravity"则是"这个View所靠近的位置"。 - Ogre
17
如果将android:gravity设置为左侧,而其子视图的android:layout_gravity设置为右侧,子视图会对齐到哪一侧? - Thupten
2
正如@Suragch在他的回答中所评论的那样,layout_gravity仅适用于LinearLayout和FrameLayout。然而,LinearLayout也有其限制。 - Marco Luglio
1
@Thupten 很好的问题。我猜一个会占上风(我猜是孩子的layout_gravity),而另一个只是占上风者的默认值。 - Trilarion
显示剩余2条评论

605

内部 - 外部

  • gravity用于排列视图中内部的内容。
  • layout_gravity用于排列视图外部的位置。

有时候看一张图片也很有帮助,绿色和蓝色是TextViews,其他两个背景颜色是LinearLayouts

enter image description here

注释

  • layout_gravity对于RelativeLayout中的视图无效。请将其用于LinearLayoutFrameLayout中的视图。更多详情请参见我的补充答案
  • 视图的宽度(或高度)必须大于其内容。否则gravity将没有任何效果。因此,wrap_contentgravity在一起无意义。
  • 视图的宽度(或高度)必须小于其父项。否则,layout_gravity将没有任何效果。因此,match_parentlayout_gravity在一起无意义。
  • layout_gravity=center在这里看起来与layout_gravity=center_horizontal相同,因为它们位于垂直线性布局中。你无法在这种情况下垂直居中,所以layout_gravity=center只在水平方向上居中。
  • 本答案仅涉及在布局内设置视图的gravitylayout_gravity。要了解在父布局本身设置gravity时会发生什么,请查看我上面提到的补充回答。(概括:在RelativeLayoutgravity效果不好,但在LinearLayout上很有用。)

因此,请记住:layout_gravity安排一个视图在其布局中。而Gravity排列视图内部的内容。

xml

以下是上面图片的xml供您参考:

<?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:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#e3e2ad"
        android:orientation="vertical" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:textSize="24sp"
            android:text="gravity=" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="left"
            android:text="left" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center_horizontal"
            android:text="center_horizontal" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="right"
            android:text="right" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center"
            android:text="center" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#d6c6cd"
        android:orientation="vertical" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:textSize="24sp"
            android:text="layout_gravity=" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="left"
            android:background="#bcf5b1"
            android:text="left" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:background="#aacaff"
            android:text="center_horizontal" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="right"
            android:background="#bcf5b1"
            android:text="right" />

        <TextView
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:background="#aacaff"
            android:text="center" />

    </LinearLayout>

</LinearLayout>

相关


2
看到可视化后似乎更容易了,谢谢Suragch。 - Haritsinh Gohil

480

两者的区别

android:layout_gravity是View的外部对齐方式。指定View应该接触其父元素边框的方向。

android:gravity是View的内部对齐方式。指定其中内容应该对齐的方向。

HTML/CSS等价物

(如果您有网页开发背景)

Android                 | CSS
————————————————————————+————————————
android:layout_gravity  | float
android:gravity         | text-align

记忆技巧

layout-gravity理解为“布局外重力”。


1
当你拥有网络开发背景时,它会更有意义。 - Haritsinh Gohil

43

简短回答:使用android:gravitysetGravity()控制容器中所有子视图的对齐方式;使用android:layout_gravitysetLayoutParams()控制容器中单个视图的对齐方式。

详细说明:要控制线性布局(例如LinearLayoutRadioGroup)容器中的对齐方式,有两种方法:

  1. 控制LinearLayout容器中所有子视图的对齐方式(就像您在书中所做的那样),请在布局XML文件中使用android:gravity(而不是android:layout_gravity),或者在代码中使用setGravity()方法。

  2. 要控制容器中子视图的对齐方式,请使用android:layout_gravity XML属性。在代码中,需要获取视图的LinearLayout.LayoutParams并设置其对齐方式。以下是一个示例代码,它将一个按钮设置为水平方向容器底部:

import android.widget.LinearLayout.LayoutParams;
import android.view.Gravity;
...

Button button = (Button) findViewById(R.id.MyButtonId);
// need to cast to LinearLayout.LayoutParams to access the gravity field
LayoutParams params = (LayoutParams)button.getLayoutParams(); 
params.gravity = Gravity.BOTTOM;
button.setLayoutParams(params);
对于水平排列的LinearLayout容器,其子视图的水平对齐方式是一个接一个地左对齐,并且不能更改。设置android:layout_gravitycenter_horizontal是没有效果的。默认的垂直对齐方式是居中 (或者是center_vertical),可以更改为上部或下部。实际上,layout_gravity的默认值是-1,但Android将它放置在垂直居中位置。
要改变水平线性容器中子视图的水平位置,可以使用子视图的layout_weight、margin和padding属性。
类似地,对于垂直视图组容器,其子视图的垂直对齐方式是一个接一个地从上往下对齐的,也无法更改。默认的水平对齐方式是居中 (或者是center_horizontal),可以更改为左侧或右侧。
实际上,例如按钮之类的子视图还有android:gravity的XML属性和setGravity()方法用于控制其子视图--其中的文本。 Button.setGravity(int)与此链接:developer.android.com条目

38
根据我的理解,layout_gravity是视图在其父视图中的重力方式,而gravity是该视图内子视图的重力方式。
我认为这个理解是正确的,但最好的方法是自己尝试一下。

30

观察图片以更清楚地了解重力。


15

如果我们想设置视图内内容的重力,那么我们将使用"android:gravity",如果我们想在父视图中设置此视图(作为整体)的重力,则我们将使用"android:layout_gravity"


9
一个容易记忆的技巧是地心引力只对我们在地球内部有效。因此,android:gravity 是针对视图内部的。
请记住,在 layout_gravity 中的out,这将帮助您记住 android:layout_gravity 是指视图外部

9

我想在这里加入我的解释 - 我来自iOS背景,以下是我对iOS术语的理解:

Layout Gravity 影响您在父视图中的位置。 Gravity 影响您内部子视图的位置。

换句话说,Layout Gravity 定位您本身,而 Gravity 定位您的子视图。


7
gravitylayout-gravity之间有许多区别。我将解释一下这两个概念的经验(所有信息都是基于我的观察和一些网站所得到的)。

FrameLayout中Gravity和Layout-gravity的用法......

注意:

  1. Gravity用于视图内容中,因为某些用户有答案,对于所有ViewGroup Layout都是相同的。

  2. Layout-gravity与父视图一起使用,因为某些用户有答案。

  3. Gravity和Layout-gravityFrameLayout子节点中更加有用。我们不能在FrameLayout的标签中使用Gravity和Layout-gravity

  4. 我们可以使用layout-gravityFrameLayout中任何位置设置子视图。

  5. 我们可以在FrameLayout中使用每个单独的Gravity值(例如:center_verticalcenter_horizontalcentertop等),但在其他ViewGroup布局中不可能。

  6. FrameLayout完全依靠layout-gravity工作。例如:如果您使用FrameLayout,则不需要更改整个布局以添加新的视图。您只需将视图作为最后一个添加到FrameLayout中,并为其赋予layout-gravity值。(这是FrameLayout与layout-gravity的优势)。

看一个例子......

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:textSize="25dp"
        android:background="#000"
        android:textColor="#264bd1"
        android:gravity="center"
        android:layout_gravity="center"
        android:text="Center Layout Gravity"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:textSize="25dp"
        android:background="#000"
        android:textColor="#1b64b9"
        android:gravity="bottom"
        android:layout_gravity="bottom|center"
        android:text="Bottom Layout Gravity" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:textSize="25dp"
        android:background="#000"
        android:textColor="#d75d1c"
        android:gravity="top"
        android:layout_gravity="top|center"
        android:text="Top Layout Gravity"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:textSize="25dp"
        android:background="#000"
        android:layout_marginTop="100dp"
        android:textColor="#d71f1c"
        android:gravity="top|right"
        android:layout_gravity="top|right"
        android:text="Top Right Layout Gravity"/>


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:textSize="25dp"
        android:background="#000"
        android:layout_marginBottom="100dp"
        android:textColor="#d71cb2"
        android:layout_gravity="bottom"
        android:gravity="bottom"
        android:text="Top Left Layout Gravity"/>

</FrameLayout>

输出: -

g1

在LinearLayout中使用gravity和layout-gravity.....

Gravity与上述工作原理相同,但不同之处在于我们可以在LinearLayout ViewRelativeLayout View中使用Gravity,而在FrameLayout View中这是不可能的。

纵向LinearLayout....

注意:- 在此,我们只能设置layout_gravity的3个值,即(left|right| center(也称为center_horizontal))。

请看以下示例:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:textSize="25dp"
        android:background="#000"
        android:textColor="#264bd1"
        android:gravity="center"
        android:layout_gravity="center_horizontal"
        android:text="Center Layout Gravity \nor \nCenter_Horizontal"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:textSize="25dp"
        android:background="#000"
        android:layout_marginTop="20dp"
        android:textColor="#d75d1c"
        android:layout_gravity="right"
        android:text="Right Layout Gravity"/>


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:textSize="25dp"
        android:background="#000"
        android:layout_marginBottom="100dp"
        android:textColor="#d71cb2"
        android:layout_gravity="left"
        android:layout_marginTop="20dp"
        android:gravity="bottom"
        android:text="Left Layout Gravity"/>

</LinearLayout>

输出:

g2

使用水平方向的LinearLayout....

注意:这里我们还可以设置layout_gravity的3个值,即(top|bottom|center(也称为center_vertical))。

看一个例子:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="120dp"
        android:layout_height="100dp"
        android:textSize="25dp"
        android:background="#000"
        android:textColor="#264bd1"
        android:gravity="center"
        android:layout_gravity="bottom"
        android:text="Bottom \nLayout \nGravity"/>

    <TextView
        android:layout_width="120dp"
        android:layout_height="100dp"
        android:textSize="25dp"
        android:background="#000"
        android:layout_marginTop="20dp"
        android:textColor="#d75d1c"
        android:layout_gravity="center"
        android:text="Center \nLayout \nGravity"/>


    <TextView
        android:layout_width="150dp"
        android:layout_height="100dp"
        android:textSize="25dp"
        android:background="#000"
        android:layout_marginBottom="100dp"
        android:textColor="#d71cb2"
        android:layout_gravity="left"
        android:layout_marginTop="20dp"
        android:text="Left \nLayout \nGravity"/>

</LinearLayout>

输出:-

g3

注意:我们不能在RelativeLayout视图中使用layout_gravity,但我们可以使用gravity将RelativeLayout的子元素设置为相同的位置...


2
如果您在所有的视图中将 textColor 设置为白色,那就太好了。 :D - Pratik Butani
你确定吗?它会变成黑白的,这就是为什么我为每个视图使用不同的颜色。 - sushildlh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接