如何在 GridLayout最大可能的尺寸中均匀分布显示 XML 形状的子项?

问题描述

这是我想要的:

我在 GridLayout 中有一个 ConstraintLayout,我动态地向其中添加自定义 ImageButtons (BoardCells) 的多行和多列。 ImageButton 使用 shape XML 文件(下面的代码显示圆圈。

我希望 BoardCells 具有相等的宽度和高度,因此形状确实是圆形而不是椭圆形。 我还希望 BoardCells 在屏幕上占据尽可能多的空间并均匀分布。


这是我尝试过的:

我为 BoardCells 尝试了固定大小(以 dp 为单位)并将 GridLayout 的 layout_width 设置为 wrap_content,但这仅适用于非常相似的不同屏幕,并且不会使用最佳空间。 Screenshot of the GridLayout with fixed size BoardCells.

当我没有为形状和 BoardCell 设置大小时,根本不会显示任何内容,无论 GridLayout 是否具有 match_parentwrap_content0dp

所以我尝试在 GridLayout 中为所有 BoardCell 赋予相同的权重,如下所示:

GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.columnSpec = GridLayout.spec(GridLayout.UNDEFINED,1f);
params.rowSpec = GridLayout.spec(GridLayout.UNDEFINED,1f);
this.setLayoutParams(params);
this.setScaleType(ScaleType.CENTER);

但是设置 column-rowSpec 不会保持比例,所以我没有得到圆圈(这是有道理的)。 Screenshot of the GridLayout with column- and rowSpec set to 1 for every BoardCell.

所以我尝试只设置 columnSpec 并将 ScaleType 设置为 CENTERCENTER_INSIDE,希望这样可以保持比例但尽可能地拉伸。 但这仅在水平方向上拉伸并在垂直方向上采用固定大小。 Screenshot of the GridLayout with columnSpec set to 1 and ScaleType CENTER

然后我想我会为 GridLayout 实现一个 onLayoutChangedListener,但是试图将子项添加onLayoutChanged 内的 GridLayout 结果在我的日志中出现“requestLayout() 不正确调用错误

我的最后一个想法是首先显示一个空的 GridLayout 并且只有当用户按下按钮开始游戏时(该按钮仍然存在,因为您可以玩多轮)并且视图已经膨胀并显示,我收到GridLayout 的宽度和高度,并计算 BoardCells 的最大可能尺寸。 但这种方法似乎不是最佳实践。

现在我不知道该怎么做才是正确的。 我做错了什么还是有什么我根本没有想到的解决方案? 我应该试验一堆模拟设备并为不同的屏幕尺寸创建 XML 形状文件吗? 动态方法好吗?



以下是相关代码

XML 布局文件

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/wood"
android:padding="10dp"
tools:context=".MainActivity">

<androidx.gridlayout.widget.GridLayout
    android:id="@+id/board_cells"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintBottom_toTopOf="@+id/guideline70"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/guideline8"
    android:layout_margin="10dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>

我使用以下代码使用自定义 ImageButton 填充此 GridLayout:

gridLayoutBoard.setUseDefaultMargins(true);
gridLayoutBoard.setRowCount(10);
gridLayoutBoard.setColumnCount(6);
for (int i = gridLayoutBoard.getRowCount()-1; i >= 0; i--) {
    for (int j = 0; j < gridLayoutBoard.getColumnCount(); j++) {
        if (j == 0 || j == 5) {
            Indikator text= new TextView;
            gridLayoutBoard.addView(text);
        } else {
            BoardCell boardCell = new BoardCell(this);
            gridLayoutBoard.addView(boardCell);
        }
    }
}

ImageButtons (BoardCells) 将它们的背景设置为这个选择器:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <layer-list>
            <item android:drawable="@drawable/cell_solid"/>
            <item android:drawable="@drawable/cell_gradient"/>
        </layer-list>
    </item>
</selector>

使用以下实体形状和具有相同大小和形状的渐变:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/grey_cell_dings" />
    <size
        android:width="30dp"
        android:height="30dp"/>
</shape>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...