我想有一个2x2网格内的按钮。这只是ICS,所以我试图使用新的GridLayout给定。

这是我的布局的XML:

 <?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/favorites_grid"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00ff00"
    android:rowCount="2"
    android:columnCount="2">
  <Button
      android:text="Cell 0"
      android:layout_row="0"
      android:layout_column="0"
      android:textSize="14dip" />
  <Button
      android:text="Cell 1"
      android:layout_row="0"
      android:layout_column="1"
      android:textSize="14dip" />

  <Button
      android:text="Cell 2"
      android:layout_row="1"
      android:layout_column="0"
      android:textSize="14dip" />
  <Button
      android:text="Cell 3"
      android:layout_row="1"
      android:layout_column="1"
      android:textSize="14dip" />
</GridLayout>

问题是我的视图没有为每一行均匀地拉伸。这导致GridLayout的右侧有很多额外的空间。

我尝试设置layout_gravity="fill_horizontal",但这只适用于该行的最后一个视图。这意味着单元格1会一直延伸,为单元格0提供足够的空间。

如何解决这个问题?


当前回答

你可以通过重写ViewGroup onLayout方法来提高速度。 这是我的普遍解决方案:

package your.app.package;

import android.content.Context;
import android.view.ViewGroup;

public class GridLayout extends ViewGroup {

    public GridLayout(Context context) {
        super(context);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int columns = 2;//edit this if you need different grid
        final int rows = 2;

        int children = getChildCount();
        if (children != columns * rows)
            throw new IllegalStateException("GridLayout must have " + columns * rows + " children");

        int width = getWidth();
        int height = getHeight();


        int viewWidth = width / columns;
        int viewHeight = height / rows;

        int rowIndex = 0;
        int columnIndex = 0;

        for (int i = 0; i < children; i++) {
            getChildAt(i).layout(viewWidth * columnIndex, viewHeight * rowIndex, viewWidth * columnIndex + viewWidth, viewHeight * rowIndex + viewHeight);
            columnIndex++;
            if (columnIndex == columns) {
                columnIndex = 0;
                rowIndex++;
            }
        }
    }

}

编辑: 不要忘记match_parent for children!

android:layout_width="match_parent"
android:layout_height="match_parent"

其他回答

你可以通过重写ViewGroup onLayout方法来提高速度。 这是我的普遍解决方案:

package your.app.package;

import android.content.Context;
import android.view.ViewGroup;

public class GridLayout extends ViewGroup {

    public GridLayout(Context context) {
        super(context);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int columns = 2;//edit this if you need different grid
        final int rows = 2;

        int children = getChildCount();
        if (children != columns * rows)
            throw new IllegalStateException("GridLayout must have " + columns * rows + " children");

        int width = getWidth();
        int height = getHeight();


        int viewWidth = width / columns;
        int viewHeight = height / rows;

        int rowIndex = 0;
        int columnIndex = 0;

        for (int i = 0; i < children; i++) {
            getChildAt(i).layout(viewWidth * columnIndex, viewHeight * rowIndex, viewWidth * columnIndex + viewWidth, viewHeight * rowIndex + viewHeight);
            columnIndex++;
            if (columnIndex == columns) {
                columnIndex = 0;
                rowIndex++;
            }
        }
    }

}

编辑: 不要忘记match_parent for children!

android:layout_width="match_parent"
android:layout_height="match_parent"

       <GridLayout
        android:layout_width="match_parent"
        android:layout_weight="3"
        android:columnCount="2"
        android:padding="10dp"
        android:rowCount="3"
        android:background="@drawable/background_down"
        android:layout_height="0dp">


        <androidx.cardview.widget.CardView
            android:layout_height="0dp"
            android:layout_width="0dp"
            android:layout_columnWeight="1"
            android:layout_rowWeight="1"
            android:layout_margin="10dp"
            android:elevation="10dp"
            app:cardCornerRadius="15dp"
            >
            <LinearLayout
                android:weightSum="3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                >

                <ImageView
                    android:layout_weight="2"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:layout_margin="15dp"
                    android:src="@drawable/user" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Users"
                    android:textSize="16sp"
                    android:layout_marginStart="15dp"
                    android:layout_marginLeft="15dp" />
            </LinearLayout>

        </androidx.cardview.widget.CardView>
        <androidx.cardview.widget.CardView
            android:layout_height="0dp"
            android:layout_width="0dp"
            android:layout_columnWeight="1"
            android:layout_rowWeight="1"
            android:layout_margin="10dp"
            android:elevation="10dp"
            app:cardCornerRadius="15dp"
            >
            <LinearLayout
                android:weightSum="3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                >

                <ImageView
                    android:layout_weight="2"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:layout_margin="15dp"
                    android:src="@drawable/addusers" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Add Users"
                    android:textSize="16sp"
                    android:layout_marginStart="15dp"
                    android:layout_marginLeft="15dp" />
            </LinearLayout>


        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView
            android:layout_height="0dp"
            android:layout_width="0dp"
            android:layout_columnWeight="1"
            android:layout_rowWeight="1"
            android:layout_margin="10dp"
            android:elevation="10dp"
            app:cardCornerRadius="15dp"
            >
            <LinearLayout
                android:weightSum="3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                >

                <ImageView
                    android:layout_weight="2"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:layout_margin="15dp"
                    android:src="@drawable/newspaper" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Report"
                    android:textSize="16sp"
                    android:layout_marginStart="15dp"
                    android:layout_marginLeft="15dp" />
            </LinearLayout>



        </androidx.cardview.widget.CardView>
        <androidx.cardview.widget.CardView
            android:layout_height="0dp"
            android:layout_width="0dp"
            android:layout_columnWeight="1"
            android:layout_rowWeight="1"
            android:layout_margin="10dp"
            android:elevation="10dp"
            app:cardCornerRadius="5dp"
            >
            <LinearLayout
                android:weightSum="3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                >

                <ImageView
                    android:layout_weight="2"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:layout_margin="15dp"
                    android:src="@drawable/settings" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Settings"
                    android:textSize="16sp"
                    android:layout_marginStart="15dp"
                    android:layout_marginLeft="15dp" />
            </LinearLayout>


        </androidx.cardview.widget.CardView>

    </GridLayout>

你可以在这里找到完整的教程, Android Grid Layout With CardView和OnItemClickListener

main。xml

<GridLayout
    android:id="@+id/grid_related_news"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:padding="3dp"
    android:columnCount="2">

</GridLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="0dp"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_columnWeight="1"
    android:gravity="center"
    android:padding="3dp"
    android:layout_gravity="fill_horizontal"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        app:cardBackgroundColor="@color/white"
        app:cardCornerRadius="5dp"
        app:cardElevation="2dp"
        android:layout_margin="4dp">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/img_related_news"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layoutDirection="rtl"
                android:scaleType="centerCrop"
                app:layout_constraintDimensionRatio="H,1:1"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/light_gray" />

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:background="#59000000"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/txt_related_news_title"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="12dp"
                android:layout_marginTop="6dp"
                android:layout_marginEnd="12dp"
                android:layout_marginBottom="12dp"
                android:elevation="2dp"
                android:fontFamily="@font/yekan_bold"
                android:letterSpacing="-0.1"
                android:lineSpacingExtra="4dp"
                android:maxLines="4"
                android:textColor="@color/white"
                android:textSize="13sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                tools:text="@string/lorem_ipsum_sentence" />

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

java

GridLayout grid_related_news = findViewById(R.id.grid_related_news);
View view = LayoutInflater.from(this).inflate(R.layout.related_item, (ViewGroup) grid_related_news, false);
ImageView img_related_news = view.findViewById(R.id.img_related_news);
...

grid_related_news.addView(view);

你可以用这个例子

这是一个相当老的问题,但显然很多人都感兴趣。对于像这样的4个按钮的简单布局,似乎tableelayout是实现预期结果的最简单方法。

下面的一些示例代码显示了一个表的前两行,该表有6列,横跨其父字段的宽度。每个单元格中的LinearLayout和ImageView用于允许在单元格中“打开和关闭”图像,同时保持单元格的颜色。

<TableLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:stretchColumns="1,2,3,4,5,6"
    android:background="@drawable/vertical_radio_button_background"
    android:padding="2dp">

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/brown"
            android:tag="13"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="1"
            android:background="@color/brown">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/maraschino"
            android:tag="9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="2"
            android:background="@color/maraschino">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/cayenne"
            android:tag="22"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="3"
            android:background="@color/cayenne">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/maroon"
            android:tag="18"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="4"
            android:background="@color/maroon">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/plum"
            android:tag="3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="5"
            android:background="@color/plum">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/eggplant"
            android:tag="15"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="6"
            android:background="@color/eggplant">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>
    </TableRow>

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/plum2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="1"
            android:background="@color/plum">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/lavender"
            android:tag="14"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="2"
            android:background="@color/lavender">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/carnation"
            android:tag="16"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="3"
            android:background="@color/carnation">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/light_pink"
            android:tag="23"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="4"
            android:background="@color/light_pink">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/strawberry"
            android:tag="10"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="5"
            android:background="@color/strawberry">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/magenta"
            android:tag="20"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_margin="1dp"
            android:layout_column="6"
            android:background="@color/magenta">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:src="@drawable/selected_check"
                android:visibility="invisible"/>
        </LinearLayout>
    </TableRow>
</TableLayout>

Appcompat21 GridLayout有列和行权重,可以像下面这样使用,在GridLayout中均匀地创建每个网格项,如上图所示。

<android.support.v7.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:grid="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    grid:alignmentMode="alignBounds"
    grid:columnCount="4" >

    <Button android:layout_width="0dp"
        style="?buttonStyle"
        android:layout_height="0dp"
        android:text="-1"
        grid:layout_columnWeight="1"
        grid:layout_rowWeight="1"
        grid:layout_gravity="fill" />
    ...
</<android.support.v7.widget.GridLayout>