AndroidX GridLayout:单元格内容更改时布局不正确

AndroidX GridLayout: incorrect layout when cell content changes

我正在使用 AndroidX GridLayout 使用以下 XML 布局显示 2x2 内容网格:

<androidx.gridlayout.widget.GridLayout
    android:id="@+id/gridlayout_first"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/outline"
    app:columnCount="2"
    app:rowCount="2"
    app:orientation="horizontal" >

    <com.google.android.material.button.MaterialButton
        android:text="@string/button_text"
        app:layout_columnWeight="1"
        app:layout_gravity="center"
        app:iconSize="40dp"
        app:icon="@drawable/ic_launcher_foreground" />

    <com.google.android.material.button.MaterialButton
        android:text="@string/button_text"
        app:layout_columnWeight="1"
        app:layout_gravity="center"
        app:iconSize="40dp"
        app:icon="@drawable/ic_launcher_foreground" />

    <com.google.android.material.button.MaterialButton
        android:text="@string/button_text"
        app:layout_columnWeight="1"
        app:layout_gravity="center"
        app:iconSize="40dp"
        app:icon="@drawable/ic_launcher_foreground" />

    <com.google.android.material.button.MaterialButton
        android:text="@string/button_text"
        app:layout_columnWeight="1"
        app:layout_gravity="center"
        app:iconSize="40dp"
        app:icon="@drawable/ic_launcher_foreground" />

</androidx.gridlayout.widget.GridLayout>

这是 @string/button_text"button" 时的样子:

但是当我稍微增加这个字符串的长度,到"my button",网格布局突然跳到这个:

我能理解如果网格单元格中的内容太大可能会被截断或换行,但我不明白为什么布局突然切换,以至于第二列完全丢失。

我可以通过在每个 MaterialButton 上放置一个 android:maxWidth 来解决这个问题,例如 170dp,但这并不理想,因为它不是很灵敏,也不会在更大的屏幕尺寸上使用更多可用宽度。部分问题是这个字符串的长度会根据使用的语言而改变,所以对于一些更长的翻译,我们确实可能需要额外的宽度(如果可用的话)。

所以我宁愿不在按钮宽度上设置一个固定的任意最大值,而只是将文本包裹在按钮内(丑陋但没有上面那么丑陋)。或者更好的是,如果任何单元格内容太大而无法容纳,GridLayout 可以自动从 2x2 切换到 4x1,那就太好了。

那么防止网格布局像这样可怕地跳跃的正确方法是什么,而只是将文本包装在网格单元格(按钮)内...或将网格布局切换为 4x1?

我已经将用于上述代码和屏幕截图的示例应用程序放在了 here

你的按钮没有移动到下一行,它只是试图尽可能地宽度,因为使用

        app:layout_columnWeight="1"

所以你有两个可能的解决方案 首先是去除重量和引力

    app:layout_columnWeight="1"
    app:layout_gravity="center"

或者通过添加宽度 0dp 使每列占据网格布局的一半

android:layout_width="0dp"

另外如果你想让TextView把它的content包裹起来而不填充parent,只要不需要就包裹在另一个ViewGroup里,FrameLayout适合这个,这个东西是TextView相关的,不是GridLayout

    <FrameLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_columnWeight="1"
        app:layout_gravity="center_vertical">

        <com.google.android.material.button.MaterialButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_textA"
            app:icon="@drawable/ic_launcher_foreground"
            android:layout_gravity="center"
            app:iconSize="40dp" />
    </FrameLayout>