应用于相对布局时,为什么重力不起作用?

时间:2017-02-09 16:33:57

标签: android xml android-layout relativelayout

我已经明白,如果我在文本视图中使用layout_gravity="center_horizontal",那么文本将是中心。但我不想使用它,因为我希望尽可能少的代码,最好的方法是将gravity="center_horizontal"应用于我的相对布局。我也问这个问题,因为我担心甚至会使用gravitylayout_gravity相对布局。在进行研究时,我遇到了this回答。

注意部分说:

  

不要将gravity / layout_gravity与RelativeLayout一起使用。将它们用于LinearLayouts和FrameLayouts中的视图。

即使从相对布局Android Documentation看起来非常明显,它明确地将gravity列为有效属性,但Google希望这些属性与相对布局一起使用。

如果该引用是正确的,我如何将视图置于相对布局中?

此外,这是我的代码:

请注意标题不是水平居中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:gravity="center_horizontal"
    tools:context="com.something">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Title"
        android:textAlignment="center"
        android:text="@string/app_title"
        android:layout_marginBottom="@dimen/main_spacing"
        android:textSize="24sp" />

    <AutoCompleteTextView
        android:id="@+id/enterContact"
        android:text="Enter Contact"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAlignment="center"
        android:layout_below="@+id/title"
        android:layout_marginBottom="@dimen/main_spacing" />

</RelativeLayout>

enter image description here

6 个答案:

答案 0 :(得分:11)

这是Gravity and layout_gravity on Android的补充答案。

在相对布局

中查看gravitylayout_gravity

gravitylayout_gravity不应在RelativeLayout的子视图中使用的原始声明部分错误。 gravity实际上工作正常。但是,layout_gravity无效。这可以在下面的例子中看到。浅绿色和浅蓝色是TextViews。另外两种背景颜色是RelativeLayouts。

enter image description here

如您所见,gravity有效,但layout_gravity不起作用。

gravity

的相对布局

我的original answer关于gravitylayout_gravity处理了这些属性应用于ViewGroup内的视图(特别是LinearLayout),而不是ViewGroup本身。但是,可以在gravity上设置layout_gravityRelativeLayoutlayout_gravity会影响RelativeLayout在其父级中的定位方式,因此我不会在此处理。但是gravity如何影响子视图,如下图所示。

enter image description here

我调整了所有子视图的宽度,以便更清楚地发生了什么。请注意RelativeLayout处理重力的方式是将所有子视图作为一个组进行移动并围绕布局移动它们。这意味着无论哪个视图最宽,都将决定其他所有位置。因此,如果所有子视图具有相同的宽度,则相对布局中的重力可能仅有用。

gravity

的线性布局

当您将gravity添加到LinearLayout时,它会按预期安排子视图。例如,可以通过将gravity的{​​{1}}设置为LinearLayout来“保存代码”。这样就不需要单独设置每个子视图的center_horizontally。请参阅下图中的各种选项。

enter image description here

请注意,当视图使用layout_gravity时,它会覆盖LinearLayout的重力。 (这可以在左图中两个布局的标题中看到.LinelineLayout layout_gravity设置为gravityleft,但标题TextView的right已设置到layout_gravity。)

最后的笔记

positioning views within a RelativeLayout时,一般的方法是在每个视图中添加以下内容:

  • center_horizontally
  • layout_alignParentTop
  • layout_centerVertical
  • layout_below

如果想要一次设置所有视图,layout_toRightOf可能会更好(或者可能使用样式)。

总而言之,

  • LinearLayout不适用于RelativeLayout中的子视图。
  • RelativeLayout的layout_gravity确实有效,但并不像人们期望的那样。

补充XML

图片的XML “在相对布局中查看gravitygravity

layout_gravity

图片的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" >

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

        <TextView
            android:id="@+id/tvTop1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textSize="24sp"
            android:text="Views' gravity=" />

        <!-- examples of gravity -->

        <TextView
            android:id="@+id/tvTop2"
            android:layout_below="@id/tvTop1"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="left"
            android:text="left" />

        <TextView
            android:id="@+id/tvTop3"
            android:layout_below="@id/tvTop2"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center_horizontal"
            android:text="center_horizontal" />

        <TextView
            android:id="@+id/tvTop4"
            android:layout_below="@id/tvTop3"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="right"
            android:text="right" />

        <TextView
            android:id="@+id/tvTop5"
            android:layout_below="@id/tvTop4"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center"
            android:text="center" />

    </RelativeLayout>

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

        <TextView
            android:id="@+id/tvBottom1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textSize="24sp"
            android:text="Views' layout_gravity=" />

        <!-- examples of layout_gravity -->

        <TextView
            android:id="@+id/tvBottom2"
            android:layout_below="@id/tvBottom1"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="left"
            android:background="#bcf5b1"
            android:text="left" />

        <TextView
            android:id="@+id/tvBottom3"
            android:layout_below="@id/tvBottom2"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:background="#aacaff"
            android:text="center_horizontal" />

        <TextView
            android:id="@+id/tvBottom4"
            android:layout_below="@id/tvBottom3"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="right"
            android:background="#bcf5b1"
            android:text="right" />

        <TextView
            android:id="@+id/tvBottom5"
            android:layout_below="@id/tvBottom4"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:background="#aacaff"
            android:text="center" />

    </RelativeLayout>

</LinearLayout>

图片的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" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center_horizontal"
        android:background="#e3e2ad" >

        <TextView
            android:id="@+id/tvTop1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:text="Views' gravity=" />

        <!-- examples of gravity -->

        <TextView
            android:id="@+id/tvTop2"
            android:layout_below="@id/tvTop1"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="left"
            android:text="left" />

        <TextView
            android:id="@+id/tvTop3"
            android:layout_below="@id/tvTop2"
            android:layout_width="300dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center_horizontal"
            android:text="center_horizontal" />

        <TextView
            android:id="@+id/tvTop4"
            android:layout_below="@id/tvTop3"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:background="#bcf5b1"
            android:gravity="right"
            android:text="right" />

        <TextView
            android:id="@+id/tvTop5"
            android:layout_below="@id/tvTop4"
            android:layout_width="150dp"
            android:layout_height="40dp"
            android:background="#aacaff"
            android:gravity="center"
            android:text="center" />

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:background="#d6c6cd" >

        <TextView
            android:id="@+id/tvBottom1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:text="Views' gravity=" />

        <!-- examples of layout_gravity -->

        <TextView
            android:id="@+id/tvBottom2"
            android:layout_below="@id/tvBottom1"
            android:layout_width="200dp"
            android:layout_height="40dp"
            android:gravity="left"
            android:background="#bcf5b1"
            android:text="left" />

        <TextView
            android:id="@+id/tvBottom3"
            android:layout_below="@id/tvBottom2"
            android:layout_width="300dp"
            android:layout_height="40dp"
            android:gravity="center_horizontal"
            android:background="#aacaff"
            android:text="center_horizontal" />

        <TextView
            android:id="@+id/tvBottom4"
            android:layout_below="@id/tvBottom3"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:gravity="right"
            android:background="#bcf5b1"
            android:text="right" />

        <TextView
            android:id="@+id/tvBottom5"
            android:layout_below="@id/tvBottom4"
            android:layout_width="150dp"
            android:layout_height="40dp"
            android:gravity="center"
            android:background="#aacaff"
            android:text="center" />

    </RelativeLayout>

</LinearLayout>

答案 1 :(得分:0)

测试您的布局,对我来说它正常工作(URL正确居中)。

但是,您也可以从TextView删除android:gravity="center_horizontal",并在RelativeLayout中添加android:layout_centerHorizontal="true"

答案 2 :(得分:0)

我也经常遇到RelativeLayouts和TextViews的问题。我认为这是因为TextView动态计算其大小,这阻止了它与布局的重力很好地协作。这只是我的假设之一。 我通常采用的解决方案是使用match_parent配置textview水平大小。它可能是次优解决方案,但应该有效。如果你需要一个固定大小的textView,你可以放一个固定大小的维度,也应该工作,它只给出了wrap_content的问题。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:gravity="center_horizontal"
    tools:context="com.something">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Title"
        android:textAlignment="center"
        android:text="@string/app_title"
        android:layout_marginBottom="@dimen/main_spacing"
        android:textSize="24sp" />

</RelativeLayout>

编辑: 正如@Valentino S.所建议的,添加

android:layout_centerHorizontal="true"
带有wrap_content的

也应该有效。原因在我的脑海中仍然是相同的:textView的大小稍后计算。

答案 3 :(得分:0)

试试这个:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:background="#000000"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:background="#ffffffff"
        android:text="TITLE"
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Title"
        android:textSize="24sp" />

    <AutoCompleteTextView
        android:id="@+id/enterContact"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title"
        android:layout_marginBottom="10dp"
        android:background="#ffffffff"
        android:text="Enter Contact"
        android:textAlignment="center" />

</RelativeLayout>

my answer

答案 4 :(得分:0)

作为documentation says

  

<强>机器人:重力

     

指定对象如何在X和X上定位其内容   Y轴,在自己的范围内。

     

...

     

center_horizontal

     

将对象放在其容器的水平中心,而不是更改   它的大小。

因此android:gravity="center_horizontal"将RelativeLayout水平化为其父级。没有使其内容中心水平。

请记住android:layout_gravity用于视图本身相对于父级或布局。

请注意,每个API级别的布局行为可能略有不同。需要注意的是,我们无法100%确定布局编辑器中的可视化结果是否正确。始终在真实设备中测试您的布局。

答案 5 :(得分:0)

TlDr:android:gravity Works 和RelativeLayout,如果你不想阅读解释,你可以跳到底部

编辑这是一个巨大的文字墙,请耐心等待我。

这就是我想要实现的目标:

<TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Title"
        android:textAlignment="center"
        android:text="@string/app_title"
        android:layout_marginBottom="@dimen/main_spacing"
        android:textSize="24sp"
        android:layout_centerHorizontal="true"/>  <!-- LAYOUT PARAMS WORK!!!-->

为什么这会有效,而android:gravity显然)却没有?

  1. 如果您的目标是将TextView放在布局/屏幕的水平中心,则必须让RelativeLayout知道!

  2. 这是通过名为LayoutParams的东西来实现的 - 这些是由View定义的数据结构,由View的父级使用(在本例中为RelativeLayout)

  3. 所以我们假设TextView有以下LayoutParams

    机器人:layout_centerHorizo​​ntal = “真”

  4. 你会得到这样的东西:

    enter image description here

    RelativeLayout在屏幕上分发其子视图时,沿途会运行一个回调方法 - onLayout(...) - 这是 <更复杂的方法序列的一部分em>将确定每个子视图在RelativeLayout 中的位置,这部分是通过访问每个子LayoutParams中的View来实现的,在这种情况下,该行你的TextView

    1. 这就是为什么我们说LayoutParams像link you mentioned before
    2. 一样传递给父母

      警告:无尽的混乱来源!

      查看Layout s / ViewGroup内的定位是通过LayoutParam onLayout来电{/ 1}}来完成的

      恰好有些像FrameLayout这样的布局有一个名为android:layout_gravity的LayoutParam,这会导致每个视图都可以定义的android:gravity属性混淆,这与不一样,甚至不是LayoutParam

      任何视图(例如android:gravity)都会使用

      TextView将其内容放入其中。

      示例:假设您将 TextView 更改为非常高,并且您希望文本位于TextView的底部,而不是位于顶部

      <TextView
              android:id="@+id/title"
              android:layout_width="wrap_content"
              android:layout_height="95dp"   <------------ very high!
              android:textAppearance="@style/TextAppearance.AppCompat.Title"
              android:textAlignment="center"
              android:text="@string/app_title"
              android:layout_marginBottom="@dimen/main_spacing"
              android:textSize="24sp"
              android:layout_centerHorizontal="true" <----- LayoutParams for RelativeLayout
              />
      

      TextView is CENTERED but text is at the TOP

      TextView在RelativeLayout中居中,但文字位于“框”的 TOP

      让我们使用android:gravity来管理文本位置 INSIDE THE TextView

      <TextView
              android:id="@+id/title"
              android:layout_width="wrap_content"
              android:layout_height="95dp"
              android:textAppearance="@style/TextAppearance.AppCompat.Title"
              android:textAlignment="center"
              android:text="@string/app_title"
              android:layout_marginBottom="@dimen/main_spacing"
              android:textSize="24sp"
              android:layout_centerHorizontal="true"
              android:gravity="bottom"       <---**NOT LayoutParams**, NOT passed to RLayout
              />
      

      结果:正如预期的那样,只有视图的内部发生了变化

      enter image description here

      TLDR 现在,如果你想忽略上面的所有内容,仍然使用android:gravity和RelativeLayout,RelativeLayout 也是View所以它有android:gravity属性,但你必须删除其他属性或LayoutParams将覆盖由android:gravity属性定义的行为看看android:gravity与RelativeLayout

      一起工作
      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/activity_main"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:paddingBottom="@dimen/activity_vertical_margin"
          android:paddingLeft="@dimen/activity_horizontal_margin"
          android:paddingRight="@dimen/activity_horizontal_margin"
          android:paddingTop="@dimen/activity_vertical_margin"
          android:gravity="bottom">   <!-- NOT LAYOUT PARAMS -->
      
          <TextView
              android:id="@+id/title"
              android:layout_width="wrap_content"
              android:layout_height="95dp"
              android:textAppearance="@style/TextAppearance.AppCompat.Title"
              android:textAlignment="center"
              android:text="@string/app_title"
              android:layout_marginBottom="@dimen/main_spacing"
              android:textSize="24sp"
              android:layout_centerHorizontal="true"
              />
      
          <AutoCompleteTextView
              android:id="@+id/enterContact"
              android:text="Enter Contact"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textAlignment="center"
              android:layout_below="@+id/title"
              android:layout_marginBottom="@dimen/main_spacing" />
      
      </RelativeLayout>
      

      enter image description here