GridLayout (not GridView) how to stretch all children evenly

Go To StackoverFlow.com

198

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:

 <?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>

The problem is that my views do not stretch evenly for each row. This causes a lot of extra space to the right of my GridLayout.

I tried setting layout_gravity="fill_horizontal" but that only applies to the last view on the row. This means Cell 1 stretches all the way to give enough space for Cell 0.

Thoughts on how to tackle this?

2012-04-04 17:33
by dnkoutso
Why didn't you set specific layoutwidth and layoutheight sizes on these Button elements - IgorGanapolsky 2014-01-14 17:21
Why not use TableLayout in your case - weaknespase 2014-10-17 12:16
In Lollipop we can now use the android.support.v7.widget.GridLayout, column count of 3, and then have a per each colum to achieve the desired effect without all the extra overhead, unless you are building exclusively for SDK 21 and then you can use the normal GradLayou - AllDayAmazing 2015-01-22 23:19


69

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>
2012-04-05 17:54
by HenrikS
This looks like it works. I was trying to avoid that but I dont see another way of getting around this. I could probably write my own ViewGroup class that properly measures and layout its children - dnkoutso 2012-04-06 15:25
This GridLayout with a column of 1 is pretty much LinearLayout in vertical orientation. It makes the layout more complicated. GridLayout is supposed to simplify and take away nested layout - Win Myo Htet 2012-11-13 02:15
Just found a way! android:layoutgravity="fillhorizontal". In case you are using the Support Library, then change it to grid:layoutgravity="fillhorizontal - zubietaroberto 2013-10-01 23:00
I agree with Win Myo Htet. This seems to be the answer Android is suggesting, but I fail to see how it is an improvement over a LinearLayout. I thought the reason for GridLayout was to avoid nested LinearLayouts? Now I can't see a use case for GridLayout that makes sense - Mitch 2013-11-07 23:09
@Mitch It seems the GridLayout plain isn't supposed to be used in this kind of instance. GridLayout, as far as I can tell from the docs, is supposed to help for much more complicated layouts. Imaging a layout where you want to have an small image in the top right corner, a main logo in the center and 3 text fields that should be aligned halfway between the left of the small image and the right of the center logo. GridLayout makes that simple. If you want 3 buttons evenly spaced horizontally, then LinearLayout is still the simplest - Rev Tyler 2014-03-19 20:00
As of API 21, weight is supporte - siyb 2015-01-23 14:39
The version of GridLayout in the Support Library supports weights and is backwards compatible to API 7. https://developer.android.com/reference/android/support/v7/widget/GridLayout.htm - Jacob Tabak 2015-02-09 15:25
This answer is almost perfect, except it forgets to mention you need to add compile 'com.android.support:gridlayout-v7:23.1.1' to your build.gradle fil - maninvan 2016-02-05 20:29


286

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>
2015-05-14 19:30
by PaulT
This answer should be higher up - S.D. 2015-06-25 09:10
Can this be used to fill both vertical and horizontal at the same time? I want an evenly stretched 3x3 layout but trying to have both weights doesn't work - Eddnav 2015-07-21 14:44
A special case of mine was where I had to use a FrameLayout which contained a Button and anImageView(in order to have an icon overlaid on a button which showed visual feedback when touched... long story) as part of a keypad. SettingcolumnWeightandgravityon every otherButtonworked fine, but broke on theFrameLayout. Leaving it out just for theFrameLayout` made everything lay out evenly as expected - psyren89 2015-10-01 06:57
Very good answer, but strange to see "fill parent" in API 2 - Dan Chaltiel 2015-11-26 23:12
Thank you for mentioning the v7-support version of GridLayout, I had no idea it existe - Mavamaarten 2016-09-09 08:51
the key is the combination of android:layout_width="0dp" and grid:layout_columnWeight="1". More generally to make cells not stretch BOTH horizontally AND vertically use android:layout_width="0dp", android:layout_height="0dp", grid:layout_columnWeight="1" & grid:layout_rowWeight="1"rockhammer 2016-10-15 20:59
Please consider including dependenciesAlwin Kesler 2017-01-13 01:07
Hello, interesting answer but how is it possible to add grid:layout_columnWeight="1" programmatically for inflated childrens - Waza_Be 2018-02-25 22:43
dependency implementation 'com.android.support:gridlayout-v7:28.0.0 - M.Zain 2019-02-11 18:44
@S.D. why?! It's not a direct answer to the question that's why should not be accepted answer. It applies to "horizontal-stretch" only - FARID 2019-03-03 06:32


64

enter image description here

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

2015-08-29 22:31
by onusopus
how do you center child views if i have only two colums - Muhammad Babar 2016-01-14 07:45
This worked for m - user300375 2016-04-20 07:56
compile "com.android.support:gridlayout-v7:$supportVersion"Miha_x64 2017-03-24 10:24
In my case, after adding the compile directive - additionally had to provide this "include" call in the xml in order to be able to access the grid attributes (like app:columnCount="2") : xmlns:app="http://schemas.android.com/apk/lib/android.support.v7.widget.GridLayout"Gene Bo 2017-10-06 20:06


33

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);
2012-06-26 15:07
by Rotemmiz
seems to break when useDefaultMargins="true" - works perfectly with them set to falseRichard Le Mesurier 2014-07-29 13:27
Can anyone tell me, where I've to add this code - Arsalan Mehmood 2015-04-12 14:19
Exactly in onCreate u have to add this code - Harish Reddy 2016-07-21 09:19


31

Starting in API 21 without v7 support library with ScrollView:

enter image description here

XML:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <GridLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:columnCount="2"
            >

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_columnWeight="1"
            android:gravity="center"
            android:layout_gravity="fill_horizontal"
            android:background="@color/colorAccent"
            android:text="Tile1" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_columnWeight="1"
            android:gravity="center"
            android:layout_gravity="fill_horizontal"
            android:background="@color/colorPrimaryDark"
            android:text="Tile2" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_columnWeight="1"
            android:gravity="center"
            android:layout_gravity="fill_horizontal"
            android:background="@color/colorPrimary"
            android:text="Tile3" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_columnWeight="1"
            android:gravity="center"
            android:layout_gravity="fill_horizontal"
            android:background="@color/colorAccent"
            android:text="Tile4" />

    </GridLayout>
</ScrollView>
2016-07-01 10:30
by t0m


11

Try adding the following to your GridLayout spec. That should work.

android:useDefaultMargins="true"
2012-06-28 12:31
by Aviral
And with that, I can call it a GridLayout again - clwhisk 2015-04-10 14:08
Should but actually doesn't - m0skit0 2017-03-16 09:58


10

This is the right answer

<?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:layout_columnWeight="1"
        android:layout_rowWeight="1"
        android:textSize="14dip" 
        />
    <Button
        android:text="Cell 1"
        android:layout_row="0"
        android:layout_column="1"
        android:textSize="14dip"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1"/>

    <Button
        android:text="Cell 2"
        android:layout_row="1"
        android:layout_column="0"
        android:textSize="14dip"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1"/>
    <Button
        android:text="Cell 3"
        android:layout_row="1"
        android:layout_column="1"
        android:textSize="14dip"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1"/>
</GridLayout>
2017-04-21 07:21
by the_prole
Sry for commenting so late but please add a little explanation to your answe - vatbub 2018-01-15 23:55
Attribute layout_columnWeight is only used in API level 21 and highe - Vikash Parajuli 2018-04-02 10:06


6

I finally found the solution. As Rotemmiz said, you have to do it dynamically afterwards. This code stretches the buttons to fill the view horizontally, but the same can be done for vertically.

public void fillview(android.support.v7.widget.GridLayout gl)
{
    Button buttontemp;

    //Stretch buttons
    int idealChildWidth = (int) ((gl.getWidth()-20*gl.getColumnCount())/gl.getColumnCount());
    for( int i=0; i< gl.getChildCount();i++)
    {
        buttontemp = (Button) gl.getChildAt(i);
        buttontemp.setWidth(idealChildWidth);
    }
}

(The 20 is for the internal and external padding and margins. This could be done more universally, but this is far cleaner)

Then it can be called like this:

    android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout)findViewById(R.id.buttongrid);
    ViewTreeObserver vto = gl.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Override public void onGlobalLayout() 
    {

            android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout) findViewById(R.id.buttongrid);
            fillview(gl);

            ViewTreeObserver obs = gl.getViewTreeObserver();
            obs.removeGlobalOnLayoutListener(this);
    }});

It must be done with an observer because we need to wait for the view to be drawn before we call the views.

2013-03-11 14:44
by dberm22


6

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'
}
2016-11-15 20:46
by Nashe
The GridLayout.LayoutParams with GridLayout.spec( GridLayout.UNDEFINED, 1f) worked great only when grid:useDefaultMargins was false. Also, lParams.width = 0 seems like it has no use since width and height are set by LayoutParams - ichalos 2017-04-02 17:57


3

You can make this lot faster by overriding ViewGroup onLayout method. This is my universal solution:

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++;
            }
        }
    }

}

EDIT: Don't forget match_parent for children!

android:layout_width="match_parent"
android:layout_height="match_parent"
2015-04-26 13:35
by user1557434
Could be good, but needs support for children padding & margi - Pascal 2016-04-06 16:43
Children padding is supported, because it's attribute set on child. To add margin support, just modify line with "layout" function as follows (where margin variable is margin in pixels): getChildAt(i).layout(viewWidth * columnIndex + margin, viewHeight * rowIndex + margin, viewWidth * columnIndex + viewWidth - margin, viewHeight * rowIndex + viewHeight - margin);user1557434 2016-04-11 14:39


2

The best solution I could find is to use a linear layout(horizontal) for each row you want and within it assign the button (cell) width to 0dp and the weight to 1. For each of the linear layouts(rows) assign the height to 0dp and the weight to 1. Find the code below- also android:layout_gravity="center_vertical" is used to align the buttons in a row in case they contain variable length text. Use of 0dp and weight it a pretty neat yet not so well known trick.

<LinearLayout
 android:id="@+id/parent_layout"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="@drawable/button_bue_3d"
 android:orientation="vertical" >

            <LinearLayout
                android:id="@+id/layout_row1"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"

                android:orientation="horizontal" >

                <Button
                    android:id="@+id/button1"
                    style="?android:attr/buttonStyleSmall"
                   android:layout_height="wrap_content"
                   android:layout_width="0dp"
                   android:layout_weight="1"
                    android:clickable="false"
                   android:layout_gravity="center_vertical"
                    android:text="ssssssssssssssssssssssssss" />

                <Button
                    android:id="@+id/button2"
                    style="?android:attr/buttonStyleSmall"
                    android:clickable="false"
                    android:layout_height="wrap_content"
                     android:layout_width="0dp"
                   android:layout_weight="1"
                   android:layout_gravity="center_vertical"
                    android:text="sggggggg" />


            </LinearLayout>

            <LinearLayout
                android:id="@+id/layout_row2"
                android:layout_weight="1"
                android:layout_width="match_parent"
                  android:layout_height="0dp"

                android:orientation="horizontal" >

                <Button
                    android:id="@+id/button3"
                    style="?android:attr/buttonStyleSmall"
                    android:layout_height="wrap_content"
                     android:layout_width="0dp"
                   android:layout_weight="1"
                    android:layout_gravity="center_vertical"
                    android:text="s" />

                <Button
                    android:id="@+id/button4"
                    style="?android:attr/buttonStyleSmall"
                    android:layout_height="wrap_content"
                     android:layout_width="0dp"
                   android:layout_weight="1"
                    android:clickable="false"
                     android:layout_gravity="center_vertical"
                    android:text="s" />


            </LinearLayout>


       </LinearLayout>
2014-11-21 12:22
by jai


0

I wanted to have a centered table with the labels right aligned and the values left aligned. The extra space should be around the table. After much experimenting and not following what the documentation said I should do, I came up with something that works. Here's what I did:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical" >

<GridLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:columnCount="2"
    android:orientation="horizontal"
    android:useDefaultMargins="true" >

    <TextView
        android:layout_gravity="right"
        android:text="Short label:" />

    <TextView
        android:id="@+id/start_time"
        android:layout_gravity="left"
        android:text="Long extended value" />

    <TextView
        android:layout_gravity="right"
        android:text="A very long extended label:" />

    <TextView
        android:id="@+id/elapsed_time"
        android:layout_gravity="left"
        android:text="Short value" />
</GridLayout>

This seems to work but the GridLayout shows the message:

"This GridLayout layout or its LinearLayout parent is useless"

Not sure why it is "useless" when it works for me.

I'm not sure why this works or if this is a good idea, but if you try it and can provide a better idea, small improvement or explain why it works (or won't work) I'd appreciate the feedback.

Thanks.

2013-11-08 02:17
by Mitch
This looks good in the layout editor, but fails when it runs. :- - Mitch 2013-11-11 21:24
The "parent is useless" message is because you have a wrapcontent inside a wrapcontent and it is the only element in there as far as I can see - Ben Wilkinson 2013-11-21 23:47


0

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>
2014-12-08 18:24
by hBrent


0

Old question, but wanted to add my solution. I created a "linear grid layout" that simulates a grid but using nested linear layouts. This allows it to stretch to fill up the space.

http://zerocredibility.wordpress.com/2014/12/18/linear-grid-layout/

2014-12-18 23:18
by Jeffrey Blattman


0

Here you are :

Button button = new Button(this);
// weight = 1f , gravity = GridLayout.FILL 
GridLayout.LayoutParams param= new GridLayout.LayoutParams(GridLayout.spec(
            GridLayout.UNDEFINED,GridLayout.FILL,1f),
            GridLayout.spec(GridLayout.UNDEFINED,GridLayout.FILL,1f));
// Layout_height = 0 ,Layout_weight = 0
params.height =0;                                                                                                           
params.width = 0;
button.setLayoutParams(param);
2017-12-25 20:41
by Nguyen Hoà


0

I wish this helps some one

Result

enter image description here

enter image description here

Code:

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 0x0"
        grid:layout_column="0"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="0"
        grid:layout_rowWeight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 0x1"
        grid:layout_column="1"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="0"
        grid:layout_rowWeight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 0x2"
        grid:layout_column="2"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="0"
        grid:layout_rowWeight="1" />


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 1x0"
        grid:layout_column="0"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="1"
        grid:layout_rowWeight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 1x1"
        grid:layout_column="1"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="1"
        grid:layout_rowWeight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 1x2"
        grid:layout_column="2"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="1"
        grid:layout_rowWeight="1" />


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 2x0"
        grid:layout_column="0"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="2"
        grid:layout_rowWeight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 2x1"
        grid:layout_column="1"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="2"
        grid:layout_rowWeight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 2x2"
        grid:layout_column="2"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="2"
        grid:layout_rowWeight="1" />


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 3x0"
        grid:layout_column="0"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="3"
        grid:layout_rowWeight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 3x1"
        grid:layout_column="1"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="3"
        grid:layout_rowWeight="1" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="item 3x2"
        grid:layout_column="2"
        grid:layout_columnWeight="1"
        grid:layout_gravity="center"
        grid:layout_row="3"
        grid:layout_rowWeight="1" />

</android.support.v7.widget.GridLayout>
2019-02-11 20:32
by M.Zain


-2

Here is what I did and I'm happy to say that this worked for me. I too wanted a 2x2, 3x3 etc. grid of items to cover the entire screen. Gridlayouts do not adhere to the width of the screen. LinearLayouts kind of work but you cant use nested weights.

The best option for me was to use Fragments I used this tutorial to get started with what I wanted to do.

Here is some code:

Main Activity:

public class GridHolderActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main_6);
    }
}

activity_main_6 XML (inflates 3 fragments)

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <fragment
        android:id="@+id/frag1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:name=".TwoHorizontalGridFragment"
        tools:layout="@layout/two_horiz" />
    <fragment
        android:id="@+id/frag2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:name=".TwoHorizontalGridFragment"
        tools:layout="@layout/two_horiz" />
    <fragment
        android:id="@+id/frag3"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:name=".Grid.TwoHorizontalGridFragment"
        tools:layout="@layout/two_horiz" />

Base fragment layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_gravity="center"
    android:layout_height="match_parent">

    <ImageQueue
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/img1"
        android:layout_weight="1"/>


    <ImageQueue
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/img2"
        android:layout_weight="1"/>
</LinearLayout>

Fragment Class (only handles initialization of a custom view) inflates 2 tiles per fragment

public class TwoHorizontalGridFragment extends Fragment {
private View rootView;

private ImageQueue imageQueue1;
private ImageQueue imageQueue2;

@Override
public View onCreateView(LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    /**
     * Inflate the layout for this fragment
     */
    rootView = inflater.inflate(
            R.layout.two_horiz, container, false);
    return rootView;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    imageQueue1 = (ImageQueue)rootView.findViewById(R.id.img1);
    imageQueue2 = (ImageQueue)rootView.findViewById(R.id.img2);
    imageQueue1.updateFiles();
    imageQueue2.updateFiles();
}

}

Thats it!

This is a weird work around to using nested weights, essentially. It gives me a perfect 2x3 grid that fills the entire screen of both my 10 inch tablet and my HTC droid DNA. Let me know how it goes for you!

2014-10-15 20:50
by Nlinscott
This is a bad approach as you are having multiple fragments which have a whole lot of complex structure to do a simple taks that can be achieved by using a gridview/gridlayout - Raykud 2015-04-30 22:22
The OP said they needed a 2x2 grid for a few buttons. Youre right, this is way to complex. For layouts with more text, views and other content, fragments are the way to go. Also, this would only be useful if the layouts were totally static and NOT dynamically built - Nlinscott 2015-05-04 02:42
Now that there is more support for GridLayouts in API 21, this approach is overkil - Nlinscott 2015-08-04 12:00
Ads