如何以编程方式使用 ImageButtons 填充网格?

How do I fill a grid with ImageButtons programmatically?

我是 Android 开发的新手,所以我一直在开发国际象棋应用程序以自学。但是,我现在被困住了。本质上,我需要一种绘制 8x8 ImageButton 网格的好方法,这样:

  1. 按钮填满整个网格
  2. 网格 space 在按钮之间均匀分布
  3. 按钮之间没有间隙(澄清 #2)
  4. 网格是方形的,大小可以控制(我希望能够根据屏幕大小自动调整大小)。

或者,简单地说,它应该看起来像一个标准的棋盘:)

我试过几种布局都没有成功。目前,这是我能做的最好的事情:

我在 PlayGameActivity(应该绘制棋盘的地方)中以下列方式使用 GridLayout:

public void onStart(){
    super.onStart();

    board = (GridLayout)findViewById(R.id.chessboard);
    board.setColumnCount(8);
    board.setRowCount(8);

    for(int i = 0; i < 8; i++){
        for(int j = 0; j < 8; j++){
            ImageButton square = squares[i][j] = new ImageButton(this);
            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.rightMargin = 0;
            params.topMargin = 0;
            params.height = params.WRAP_CONTENT;
            params.width = params.WRAP_CONTENT;
            params.setGravity(Gravity.FILL);
            params.rowSpec = GridLayout.spec(i);
            params.columnSpec = GridLayout.spec(j);

            board.addView(square, params);

            //board.addView(square);
        }
    }}

棋盘是通过 XML 定义的,如下所示:

<GridLayout
    android:id="@+id/chessboard"
    android:layout_width="353dp"
    android:layout_height="353dp"
    android:layout_marginBottom="104dp"
    android:layout_marginEnd="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="104dp"
    android:background="#000000"
    android:gravity="center_horizontal"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:layout_constraintBottom_creator="1"
    tools:layout_constraintLeft_creator="1"
    tools:layout_constraintRight_creator="1"
    tools:layout_constraintTop_creator="1">
</GridLayout>

我为此类问题找到的所有解决方案都是 Android XML 的形式。也许我对这种方法的担忧是基于无知,但我的理解是我必须将 64 个方块复制并粘贴到 GridLayout 或其他东西中。另外,我不确定如何使用这种方法根据屏幕尺寸调整大小。理想情况下,我正在寻找一个严格的程序化解决方案(无论如何,这是我首选的 UI 设计方法)。

我的建议是使用 include (link) 与 xml 进行模块化:

<include layout="@layout/titlebar"/>

使用include 允许您在自己的文件中编写一段XML 代码,然后多次使用它。我还建议在大多数情况下不要使用 GridLayout,因为它们不能像其他一些布局类型那样为您提供那么多的控制权。如果这是我的代码,我会这样做:

  1. 在自己的 XML 文件中创建一个 ImageButton "square" android:layout_weight="1"
  2. 使用 android:orientation="horizontal"android:layout_weight="1"android:weightSum="8" 在自己的 XML 文件中创建一个 LinearLayout "row",然后复制并粘贴8 includelayout="@layout/[your_image_button]"
  3. 在您当前拥有 GridLayout 的地方创建一个外部 LinearLayout。这个会有 android:orientation="vertical"android:weightSum="8"。然后用 layout="@layout/[your_linear_layout_row]".
  4. 复制粘贴 8 includes

有很多方法可以做到这一点,但这种方法可以让您更好地控制所有内容的空间布局,其逻辑与您目前使用的 'array of arrays' 方法非常相似用于动态布置所有内容。如果您想采用动态 java 路线,我的建议是在 java 中执行这种基于 LinearLayout 的网格方法(您甚至可以在 XML 中创建 ImageButton 并使用 LayoutInflater 来膨胀 ImageButton 的副本)。在外层for循环中,可以新建一个LinearLayout,添加到外层LinearLayout中;然后在内部 for 循环中,创建 ImageButton 并将其添加到内部 LinearLayout.

编辑:关于行不同的好处!这使得纯 XML 溶液不太干净。如果你选择纯 XML,我会做两次上面的步骤 2:一次是白色,然后是黑色;另一次先黑后白。对于黑色瓷砖,这可能看起来像:

<include layout="@layout/your_imagebutton"
  android:backgroundColor="#000"
/>

如果这种方法对您来说太麻烦,您可以通过循环遍历 LinearLayout 行和 ImageButton 图块来动态设置颜色以设置背景颜色。我认为您会发现它比您的 GridLayout 方法更容易。