网格布局和行/列跨度问题

126

Android Developers Blog中介绍了GridLayout布局的文章中展示了这张图,它展示了跨度如何影响自动索引分配:

automatic index allocation

我正在尝试使用GridLayout实现这一点。以下是我目前的代码:

<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.commonsware.android.gridlayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    app:orientation="horizontal"
    app:columnCount="8">

    <Button
        app:layout_columnSpan="2"
        app:layout_rowSpan="2"
        android:layout_gravity="fill_horizontal"
        android:text="@string/string_1"/>

  <Button
    app:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_2"/>

  <Button
    app:layout_rowSpan="4"
    android:text="@string/string_3"/>

  <Button
    app:layout_columnSpan="3"
    app:layout_rowSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_4"/>

  <Button
    app:layout_columnSpan="3"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_5"/>

  <Button
    app:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_6"/>

  <android.support.v7.widget.Space
    app:layout_column="0"
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

</android.support.v7.widget.GridLayout>

为了确保每列都有最小宽度,我不得不引入<Space>元素,否则我将拥有一堆零宽度的列。

然而,即使使用它们,我仍然会得到这个:

sample GridLayout

值得注意的是:

  • 尽管设置了android:layout_gravity="fill_horizontal",我的跨越多列的小部件并没有填满横跨的列

  • 虽然设置了android:layout_rowSpan的值,但没有任何内容跨越行

有人能够使用GridLayout复制博客文章中的图表吗?

谢谢!


186
我猜你甚至会问问题 :) - StackOverflowed
5个回答

81

感觉有点像hack,但我通过添加额外的列和行来实现了正确的外观。然后我在每一行中填充了一个空格来定义高度,并在每一列中填充了一个空格来定义宽度。为了增加灵活性,我想这些空格大小可以在代码中设置,以提供类似于权重的东西。我尝试添加截屏,但我没有足够的声望。

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnCount="9"
android:orientation="horizontal"
android:rowCount="8" >

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill"
    android:layout_rowSpan="2"
    android:text="1" />

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="2" />

<Button
    android:layout_gravity="fill_vertical"
    android:layout_rowSpan="4"
    android:text="3" />

<Button
    android:layout_columnSpan="3"
    android:layout_gravity="fill"
    android:layout_rowSpan="2"
    android:text="4" />

<Button
    android:layout_columnSpan="3"
    android:layout_gravity="fill_horizontal"
    android:text="5" />

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="6" />

<Space
    android:layout_width="36dp"
    android:layout_column="0"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="1"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="2"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="3"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="4"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="5"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="6"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="7"
    android:layout_row="7" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="0" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="1" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="2" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="3" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="4" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="5" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="6" />

</GridLayout>

screenshot


7
在我看来,这比迄今为止提出的另一个解决方案要逐步更加简便一些——至少在这里,硬编码的大小在“空间”元素中。我为未来的读者添加了一张截图。谢谢! - CommonsWare
为什么 rowCount 被设置为 8?我们需要 4 行(最大 rowSpan 的大小)加上额外的一行用于 Space,所以应该是 5。我错过了什么吗? - curioustechizen
5
我发现这个解决方案只适用于 <Gridlayout>,而不是 <android.support.v7.widget.GridLayout> - Didia
我该如何动态设置行跨度和列跨度...以使其正常工作? - user4302606
请查看以下链接:https://dev59.com/rlsW5IYBdhLWcg3w-bL_ - user4302606
显示剩余2条评论

16
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <GridLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:columnCount="8"
        android:rowCount="7" >

        <TextView
            android:layout_width="50dip"
            android:layout_height="50dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="2"
            android:background="#a30000"
            android:gravity="center"
            android:text="1"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="50dip"
            android:layout_height="25dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="1"
            android:background="#0c00a3"
            android:gravity="center"
            android:text="2"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="25dip"
            android:layout_height="100dip"
            android:layout_columnSpan="1"
            android:layout_rowSpan="4"
            android:background="#00a313"
            android:gravity="center"
            android:text="3"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="75dip"
            android:layout_height="50dip"
            android:layout_columnSpan="3"
            android:layout_rowSpan="2"
            android:background="#a29100"
            android:gravity="center"
            android:text="4"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="75dip"
            android:layout_height="25dip"
            android:layout_columnSpan="3"
            android:layout_rowSpan="1"
            android:background="#a500ab"
            android:gravity="center"
            android:text="5"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="50dip"
            android:layout_height="25dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="1"
            android:background="#00a9ab"
            android:gravity="center"
            android:text="6"
            android:textColor="@android:color/white"
            android:textSize="20dip" />
    </GridLayout>

</RelativeLayout>

屏幕截图


2
谢谢!有趣的是,如果我从Android支持包切换到 GridLayout,布局就会出问题,这表明它们并不完全兼容。此外,我真的希望有一种方法可以在不涉及小部件大小硬连接的情况下完成此操作。我会让这个问题继续进行一段时间,看看是否还有其他答案(如果有),但如果没有更好的答案出现,我会接受你的答案。再次感谢! - CommonsWare
4
如果我从Android支持包切换到GridLayout,则布局会崩溃。实际上,那是我的错,因为我没有将必需的“android:”属性转换为使用后备的XML命名空间的“app:”属性。使用后备支持库确实可以解决该问题。 - CommonsWare
@Bondax 这个实现明确定义了网格项的高度、宽度、列宽和列跨度。当为网格(屏幕宽度)定义不同的宽度时,网格布局会在有限的空间内浮动您的网格项。这是一个项目的要求,这个解决方案完美地解决了这个问题。 - HandlerExploit
@Bondax 如果你不理解,那是因为这个例子本来就是过于简化了,因为问题只要求如此,没有更多也没有更少。 - HandlerExploit
所有上述的都可以通过RelativeLayout实现,对吧!? - Lalith B
显示剩余3条评论

6

要对列设置layout_gravity和layout_columntWeight两个属性

<android.support.v7.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView android:text="سوم شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />

    <TextView android:text="دوم شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />

    <TextView android:text="اول شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />
 </android.support.v7.widget.GridLayout>

2

Android Support V7 GridLayout库通过适应权重的原则,使得过多的空间分配变得容易。要使一列伸展,确保其内部组件定义了权重或重力。为了防止列的伸展,确保列中的一个组件没有定义权重或重力。记得在build.gradle中添加此库的依赖项。添加com.android.support:gridlayout-v7:25.0.1即可。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="2"
app:rowCount="2">

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="First"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="Second"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="Third"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"        
    app:layout_columnWeight="1"
    app:layout_rowWeight="1"
    android:text="fourth"/>

</android.support.v7.widget.GridLayout>

1

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