【问题标题】:GridLayout align children within columnGridLayout 在列内对齐子项
【发布时间】:2014-09-03 12:36:58
【问题描述】:

我有一个由 6 个孩子组成的 GridLayout。它的列数为 2。左列的子级具有 layout_gravitystart|end|fill_horizontallayout_width 的 0dp,这会导致它们填满所有可用空间。

这太棒了,它给了我如下所示的输出。

视图 4、5 和 6 只是它们需要的大小。很酷。我现在想将视图 4、5 和 6 与容器的右侧对齐,但这已被证明具有挑战性。由于GridLayout 确定列灵活性的方式,给右列的视图提供layout_gravityright 会破坏布局。第一列中的视图不再填充布局中的剩余宽度。 (据我了解,这是因为现在两列都有定义水平重力的子级,所以GridLayout 不能再将一列标记为灵活)。

有没有办法做到这一点?我真的不喜欢嵌套LinearLayouts。以下是我想要的结果。

作为参考,当前视图层次结构 XML 看起来像...

<GridLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="2">

    <View
        android:id="@+id/view1"
        android:layout_gravity="start|end|fill_horizontal" />

    <View
        android:id="@+id/view4" />

    <View
        android:id="@+id/view2"
        android:layout_gravity="start|end|fill_horizontal" />

    <View
        android:id="@+id/view5" />

    <View
        android:id="@+id/view3"
        android:layout_gravity="start|end|fill_horizontal" />

    <View
        android:id="@+id/view6" />

</GridLayout>

【问题讨论】:

  • 只是为了澄清:您是想只为右列填充空间,还是右列应该与左列具有相同的宽度?是否还要右对齐第二列中的文本?
  • 我希望右栏中的视图保持当前宽度。我希望视图的边界拥抱右侧,而不是左侧。文本确实会右对齐,但TextViews 的内部重力似乎与问题无关。
  • 我想试试这个表格布局如何..你不能使用表格布局
  • 当然可以使用TableLayout 实现我想要的外观,但这不是问题。我对GridLayout 是否可以实现我想要的东西很感兴趣。 TableLayout 将使用多个 layout() 传递来完成工作。 GridLayout 会更有效率。

标签: android android-gridlayout


【解决方案1】:

来自GridLayout的文档:

多余空间分布

同一行或列组中的多个组件被视为并行操作。只有当其中的所有组件都是灵活的时,这样的组才是灵活的。相反,位于公共边界两侧的行组和列组被视为串联。 如果其中一个元素是灵活的,则由这两个元素组成的复合组是灵活的。

要使柱子伸展,请确保其中的所有组件都定义了重力。要防止柱子拉伸,请确保柱子中的一个组件没有定义重力。

当灵活性原则不能完全消除歧义时,GridLayout 的算法偏向于更靠近其右侧和底部边缘的行和列。

(强调我的)

所以,要设计以下输出:

解释:

注意:

  • 不要将右列最大宽度分量的重心与任何轴对齐(如上、下、左、右)。当视图与轴对齐时,它不会拉伸,因为复合组将变得不灵活。这会使复合组中的其他元素收缩(即使指定了fill_horizo​​ntal,在非灵活的复合组中也是无效的)。最宽组件的宽度将是网格中右侧列的宽度。

  • 如果希望文本在内容长度增加时换行,请将视图的宽度指定为 0dp (android:layout_width="0dp"),以便网格布局动态计算宽度:

用于网格布局的 XML:

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:alignmentMode="alignBounds"
    android:background="#ffffffff"
    android:columnCount="6"
    android:columnOrderPreserved="false"
    android:orientation="horizontal"
    android:padding="5dp"
    android:useDefaultMargins="true" >

    <Button
        android:id="@+id/view1"
        android:layout_width="0dp"
        android:layout_columnSpan="4"
        android:layout_gravity="left|fill"
        android:background="#ff00BFFF"
        android:text="View 1" />

    <Button
        android:id="@+id/view4"
        android:layout_columnSpan="2"
        android:layout_gravity="right|clip_horizontal"
        android:background="#ffff0000"
        android:padding="5dp"
        android:text="hi"
        android:textColor="#ffffffff" />

    <Button
        android:id="@+id/view2"
        android:layout_width="0dp"
        android:layout_columnSpan="4"
        android:layout_gravity="left|fill"
        android:background="#ff00ff00"
        android:text="View 2 has a very very very long text" />

    <Button
        android:id="@+id/view5"
        android:layout_columnSpan="2"
        android:layout_gravity="clip_horizontal"
        android:background="#ffDDA0DD"
        android:padding="5dp"
        android:text="hello something"
        android:textColor="#ffffffff" />

    <Button
        android:id="@+id/view3"
        android:layout_width="0dp"
        android:layout_columnSpan="4"
        android:layout_gravity="left|fill"
        android:background="#ffffD700"
        android:text="View 3 has a very very very long text" />

    <Button
        android:id="@+id/view6"
        android:layout_columnSpan="2"
        android:layout_gravity="clip_horizontal|right"
        android:background="#ff4169E1"
        android:padding="5dp"
        android:text="hello world"
        android:textColor="#ffffffff" />

</GridLayout>

【讨论】:

  • 如果您使用 android:text="View 3 和稍长一点的时间来打破 view3 的长度",那么它会将右列推出屏幕。正如克里斯提到的那样,如果视图 1、2、3 中的任何一个很长,它都不会换行。它将内容推出。
  • 非常感谢您的帮助!似乎只用两列是不可能的,这很好。通过这个小练习,我确实学到了很多关于GridLayout 的知识!
  • @Chris:希望你能读到这篇文章 - android-developers.blogspot.com/2011/11/…,我觉得它很有用。
  • @InfiniteRecursion 我确实读过很多遍了,但我发现它仍然不能清楚地描述GridLayout 的能力。我开始这个追逐鹅是因为GridLayout.Alignment 似乎暗示了某些可能性developer.android.com/reference/android/widget/…
  • 这假设您知道哪个视图的文本最长。即使假设是静态数据,英语中最长的也不一定是另一种语言中最长的。
【解决方案2】:

让我修改我的答案并使用不同的方法。这是布局文件:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2" >


<TextView
    android:id="@+id/TextView1"
    android:layout_column="0"
    android:layout_columnSpan="1"
    android:layout_row="0"
    android:background="#87CEFA"
    android:text="@string/view1" />

<TextView
    android:id="@+id/TextView4"
    android:gravity="right"
    android:layout_column="1"
    android:layout_columnSpan="1"
    android:layout_row="0"
    android:layout_gravity="right"
    android:background="#FF3030"
    android:text="@string/view4" />

<TextView
    android:id="@+id/TextView2"
    android:layout_column="0"
    android:layout_columnSpan="1"
    android:layout_row="1"
    android:width="0dp"
    android:layout_gravity="fill_horizontal"
    android:background="#90EE90"
    android:text="@string/view2" />

<TextView
    android:id="@+id/TextView5"
    android:gravity="right"
    android:layout_column="1"
    android:layout_columnSpan="1"
    android:layout_row="1"
    android:background="#EE82EE"
    android:paddingLeft="36dp"
    android:layout_gravity="right"
    android:text="@string/view5" />

<TextView
    android:id="@+id/TextView3"
    android:layout_column="0"
    android:layout_columnSpan="1"
    android:layout_row="2"
    android:width="0dp"
    android:layout_gravity="fill_horizontal"
    android:background="#EEEE00"
    android:text="@string/view3" />

<TextView
    android:id="@+id/TextView6"
    android:gravity="right"
    android:layout_column="1"
    android:layout_columnSpan="1"
    android:layout_row="2"
    android:background="#EE7621"
    android:layout_gravity="right"
    android:text="@string/view6" />

</GridLayout>

结果如下:

两列的宽度由内容决定。对于 View 5,我在左侧添加了填充,即填充可用于扩展单元格的宽度(和高度)。这行得通吗?

【讨论】:

  • 这个答案需要付出很多努力,干得好!不幸的是,这不是我所追求的。 (我刚刚更新了问题以澄清我所追求的。对任何变幻莫测的道歉)。我也不会热衷于自己手动调整孩子的宽度。我相当肯定 GridLayout 可以做我所要求的,我只是遗漏了一些关键细节。
  • 更接近,但这种方法仍然存在问题。如果 Views 1、2 或 3 中的文本长度特别长,则不会换行。不幸的是,文本将继续向右并延伸到视图的边界之外。我发现防止这种情况的唯一方法是将宽度设置为 0dp,并将 layout_gravity 设置为 fill_horizo​​ntal。这反过来意味着 layout_gravity 不能在第二列中的视图上 正确 :(
  • 是的,这就是挑战。我将其称为“内容驱动”。到目前为止,我发现的唯一方法是我的第一反应。我将观看此条目,看看是否有人有更好的解决方案。
  • 有机会以编程方式实现此结果吗?
猜你喜欢
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 2018-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
  • 2017-08-08
相关资源
最近更新 更多