GridLayout (not GridView) how to stretch all children evenly

后端 未结 20 1920
独厮守ぢ
独厮守ぢ 2020-11-22 09:35

I want to have a 2x2 grid with a buttons inside. This is only ICS so I am trying to use the new GridLayout given.

Here\'s the XML of my layout:

 <         


        
相关标签:
20条回答
  • 2020-11-22 10:24

    Starting in API 21 the notion of weight was added to GridLayout. To support older android devices, you can use the GridLayout from the v7 support library.

    The following XML gives an example of how you can use weights to fill the screen width.

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.GridLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:grid="http://schemas.android.com/apk/res-auto"
    
        android:id="@+id/choice_grid"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:padding="4dp"
    
        grid:alignmentMode="alignBounds"
        grid:columnCount="2"
        grid:rowOrderPreserved="false"
        grid:useDefaultMargins="true">
    
        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            grid:layout_columnWeight="1"
            grid:layout_gravity="fill_horizontal"
            android:gravity="center"
            android:background="#FF33B5E5"
            android:text="Tile1" />
    
        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            grid:layout_columnWeight="1"
            grid:layout_gravity="fill_horizontal"
            android:gravity="center"
            android:background="#FF33B5E5"
            android:text="Tile2" />
    
        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            grid:layout_columnWeight="1"
            grid:layout_gravity="fill_horizontal"
            android:gravity="center"
            android:background="#FF33B5E5"
            android:text="Tile3" />
    
        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            grid:layout_columnWeight="1"
            grid:layout_gravity="fill_horizontal"
            android:gravity="center"
            android:background="#FF33B5E5"
            android:text="Tile4" />
    
    </android.support.v7.widget.GridLayout>
    
    0 讨论(0)
  • 2020-11-22 10:25

    UPDATE: Weights are supported as of API 21. See PaulT's answer for more details. END UPDATE There are limitations when using the GridLayout, the following quote is taken from the documentation.

    "GridLayout does not provide support for the principle of weight, as defined in weight. In general, it is not therefore possible to configure a GridLayout to distribute excess space in non-trivial proportions between multiple rows or columns ... For complete control over excess space distribution in a row or column; use a LinearLayout subview to hold the components in the associated cell group."

    Here is a small example that uses LinearLayout subviews. (I used Space Views that takes up unused area and pushes the buttons into desired position.)

    <GridLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnCount="1"
    >
        <TextView
            android:text="2x2 button grid"
            android:textSize="32dip"
            android:layout_gravity="center_horizontal" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" android:orientation="horizontal">
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button 1" />
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="start"
                android:text="Button 2" />
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
        >
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button 3" />
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="start"
                android:text="Button 4" />
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
        </LinearLayout>
    </GridLayout>
    
    0 讨论(0)
  • 2020-11-22 10:29

    Appcompat21 GridLayout has the column and row weights which can be used like below to evenly create each grid item in the gridlayout like the image above.

    <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"/>
    ...
    ...
    ...
    

    0 讨论(0)
  • 2020-11-22 10:29

    In my case I was adding the buttons dynamically so my solution required some XML part and some Java part. I had to find and mix solutions from a few different places and thought I will share it here so someone else looking for the similar solution might find it helpful.

    First part of my layout file XML...

    <android.support.v7.widget.GridLayout
        xmlns:grid="http://schemas.android.com/apk/res-auto"
        android:id="@+id/gl_Options"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        grid:useDefaultMargins="true">
    </android.support.v7.widget.GridLayout>
    

    grid:useDefaultMargins="true" is not required but I added because that looked better to me, you may apply other visual affects (e.g. padding) as mentioned in some answers here. Now for the buttons as I have to add them dynamically. Here is the Java part of my code to make these buttons, I am including only those lines related to this context. Assume I have to make buttons from as many myOptions are available to my code and I am not copying the OnClickListener code as well.

    import android.support.v7.widget.GridLayout;   //Reference to Library
    
    public class myFragment extends Fragment{
        GridLayout gl_Options;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            gl_AmountOptions = (GridLayout)view.findViewById( R.id.gl_AmountOptions );
            ...
            gl_Options.removeAllViews();     // Remove all existing views
            gl_AmountOptions.setColumnCount( myOptions.length <= 9 ? 3: 4 );  // Set appropriate number of columns
    
            for( String opt : myOptions ) {
                GridLayout.LayoutParams lParams   = new GridLayout.LayoutParams( GridLayout.spec( GridLayout.UNDEFINED, 1f), GridLayout.spec( GridLayout.UNDEFINED, 1f));
                // The above defines LayoutParameters as not specified Column and Row with grid:layout_columnWeight="1" and grid:layout_rowWeight="1"
                lParams.width = 0;    // Setting width to "0dp" so weight is applied instead
    
                Button b = new Button(this.getContext());
                b.setText( opt );
                b.setLayoutParams(lParams);
                b.setOnClickListener( myClickListener );
                gl_Options.addView( b );
            }
        }
    }
    

    As we are using GridLayout from support library and not the standard GridLayout, we have to tell grade about that in YourProject.grade file.

    dependencies {
        compile 'com.android.support:appcompat-v7:23.4.0'
        ...
        compile 'com.android.support:gridlayout-v7:23.4.0'
    }
    
    0 讨论(0)
  • 2020-11-22 10:29

    This is a fairly old question, but obviously of interest to a lot of people. For a simple layout of 4 buttons like this, it seems that a TableLayout is the easiest way to accomplish the desired result.

    Here's some example code showing the first 2 rows of a table with 6 columns spanning the width of its parent. The LinearLayout and ImageView in each cell are used to allow for the "turning on and off" of an image within the cell while having the color of the cell persist.

    <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>
    
    0 讨论(0)
  • 2020-11-22 10:31

    You can set width of every child dynamically:

    GridLayout.LayoutParams params = (GridLayout.LayoutParams) child.getLayoutParams();
        params.width = (parent.getWidth()/parent.getColumnCount()) -params.rightMargin - params.leftMargin;
        child.setLayoutParams(params);
    
    0 讨论(0)
提交回复
热议问题