Search code examples
androidandroid-gridlayout

How do I stretch a GridLayout to its parent?


I am trying to stretch the keyboard of my calculator (which is a GridLayout with buttons inside of it). It is a 5*4(columns*rows).

  1. I give GridLayout android:layout_height="match_parent" and android:layout_width="match_parent" to make its dimensions fill the available space. then
  2. I assign the column and row indices to the cells with android:layout_column an android:layout_row accordingly.

I get the following result:

1080x1920

enter image description here

The cells take an uniform width and height, but do not stretch enough to fill the whole grid. So I searched online and saw that I could assign an equal weight to each cell and the layout figures out a uniform width and height value that fills the whole grid.

(Side question: how does android determine the size of these cells in this case? why did it not make them larger/smaller than what it is here?)

So I add:

  1. android:layout_weight="1" and android:layout_height="1" to each of the buttons

I get this result:

1080x1920

enter image description here

Awesome. Looks like it is working as intended.. until I change the resolution to something else:

480x800

enter image description here

Or if I keep the same 1080x1920 resolution but force the min height of the top section to something like 280dp (279dp works fine)

enter image description here

How can I fix this? I am intending API Level 21 and I want to force the GridLayout to fill the available space no matter. I prefer the buttons to be squeezed (even have their content clipped/ invisible) rather than to shoot off the screen. To finish here is the XML:

main.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root">
<!--Top section (screen + few keys)-->
    <LinearLayout
        android:style="@style/CalculatorScreenStyle"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/top">
        <Space
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="280dp"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="40sp"
            android:hint="Enter a number here"/>
    </LinearLayout>
<!-- Keyboard layout -->
    <GridLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/keyboard"
        android:columnCount="4"
        android:rowCount="5">
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="C"
            android:id="@+id/clearButton"
            android:layout_column="0"
            android:layout_row="0" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="Button"
            android:id="@+id/button15"
            android:layout_column="1"
            android:layout_row="0" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="%"
            android:layout_column="2"
            android:layout_row="0"
            android:id="@+id/percentButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:id="@+id/divideButton"
            android:layout_column="3"
            android:layout_row="0"
            android:text="÷" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="7"
            android:layout_column="0"
            android:layout_row="1"
            android:id="@+id/sevenNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="8"
            android:layout_column="1"
            android:layout_row="1"
            android:id="@+id/eightNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="9"
            android:layout_column="2"
            android:layout_row="1"
            android:id="@+id/nineNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="+"
            android:layout_column="3"
            android:layout_row="1"
            android:id="@+id/plusButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="4"
            android:layout_column="0"
            android:layout_row="2"
            android:id="@+id/fourNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="5"
            android:layout_column="1"
            android:layout_row="2"
            android:id="@+id/fiveNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="6"
            android:layout_column="2"
            android:layout_row="2"
            android:id="@+id/sixNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="x"
            android:layout_column="3"
            android:layout_row="2"
            android:id="@+id/multiplyButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="1"
            android:layout_column="0"
            android:layout_row="3"
            android:id="@+id/oneNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="2"
            android:layout_column="1"
            android:layout_row="3"
            android:id="@+id/twoNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="3"
            android:layout_column="2"
            android:layout_row="3"
            android:id="@+id/threeNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="-"
            android:layout_column="3"
            android:layout_row="3"
            android:id="@+id/minusButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="+/-"
            android:layout_column="0"
            android:layout_row="4"
            android:id="@+id/signButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="0"
            android:layout_column="1"
            android:layout_row="4"
            android:id="@+id/zeroNumButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="."
            android:layout_column="2"
            android:layout_row="4"
            android:id="@+id/periodButton" />
        <Button
            android:style="@style/CalculatorButtonStyle"
            android:text="="
            android:layout_column="3"
            android:layout_row="4"
            android:id="@+id/equalsButton" />
    </GridLayout>
</LinearLayout>

styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="CalculatorButtonStyle" >
    <item name="android:textSize">22sp</item>
    <item name="android:layout_columnWeight">1</item>
    <item name="android:layout_rowWeight">1</item>
    <item name="android:background">#9E5EC2</item>
  </style>
  <style name="CalculatorScreenStyle">
    <item name="android:background">#ED59E8</item>
  </style>
</resources>

EDIT: As a temporary solution, I am using a vertical LinearLayout of horizontals LinearLayouts and I assing an equal weights to all the Buttons. It works fine but then I wonder what is the use of GridLayout if I have to emulate how it works myself..

enter image description here


Solution

  • When android API level < 21, it doesn't work well.

    So we can add dependency in app gradle file:

    implementation 'androidx.gridlayout:gridlayout:1.0.0'
    

    If you've still not migrated to androidx (which you ought to), then use:

    implementation 'com.android.support:gridlayout-v7:28.0.0'
    

    Then change your code.

    Use androidx.gridlayout.widget.GridLayout (or android.support.v7.widget.GridLayout, if not androidx) in your XML code.

    <androidx.gridlayout.widget.GridLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/keyboard"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:columnCount="4"
        app:rowCount="5">
    
        <Button
            android:id="@+id/clearButton"
            style="@style/CalculatorButtonStyle"
            android:text="C"
            app:layout_column="0"
            app:layout_columnWeight="1"
            app:layout_row="0"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/button15"
            style="@style/CalculatorButtonStyle"
            android:text="Button"
            app:layout_column="1"
            app:layout_columnWeight="1"
            app:layout_row="0"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/percentButton"
            style="@style/CalculatorButtonStyle"
            android:text="%"
            app:layout_column="2"
            app:layout_columnWeight="1"
            app:layout_row="0"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/divideButton"
            style="@style/CalculatorButtonStyle"
            android:text="÷"
            app:layout_column="3"
            app:layout_columnWeight="1"
            app:layout_row="0"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/sevenNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="7"
            app:layout_column="0"
            app:layout_columnWeight="1"
            app:layout_row="1"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/eightNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="8"
            app:layout_column="1"
            app:layout_columnWeight="1"
            app:layout_row="1"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/nineNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="9"
            app:layout_column="2"
            app:layout_columnWeight="1"
            app:layout_row="1"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/plusButton"
            style="@style/CalculatorButtonStyle"
            android:text="+"
            app:layout_column="3"
            app:layout_columnWeight="1"
            app:layout_row="1"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/fourNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="4"
            app:layout_column="0"
            app:layout_columnWeight="1"
            app:layout_row="2"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/fiveNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="5"
            app:layout_column="1"
            app:layout_columnWeight="1"
            app:layout_row="2"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/sixNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="6"
            app:layout_column="2"
            app:layout_columnWeight="1"
            app:layout_row="2"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/multiplyButton"
            style="@style/CalculatorButtonStyle"
            android:text="x"
            app:layout_column="3"
            app:layout_columnWeight="1"
            app:layout_row="2"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/oneNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="1"
            app:layout_column="0"
            app:layout_columnWeight="1"
            app:layout_row="3"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/twoNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="2"
            app:layout_column="1"
            app:layout_columnWeight="1"
            app:layout_row="3"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/threeNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="3"
            app:layout_column="2"
            app:layout_columnWeight="1"
            app:layout_row="3"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/minusButton"
            style="@style/CalculatorButtonStyle"
            android:text="-"
            app:layout_column="3"
            app:layout_columnWeight="1"
            app:layout_row="3"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/signButton"
            style="@style/CalculatorButtonStyle"
            android:text="+/-"
            app:layout_column="0"
            app:layout_columnWeight="1"
            app:layout_row="4"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/zeroNumButton"
            style="@style/CalculatorButtonStyle"
            android:text="0"
            app:layout_column="1"
            app:layout_columnWeight="1"
            app:layout_row="4"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/periodButton"
            style="@style/CalculatorButtonStyle"
            android:text="."
            app:layout_column="2"
            app:layout_columnWeight="1"
            app:layout_row="4"
            app:layout_rowWeight="1"/>
    
        <Button
            android:id="@+id/equalsButton"
            style="@style/CalculatorButtonStyle"
            android:text="="
            app:layout_column="3"
            app:layout_columnWeight="1"
            app:layout_row="4"
            app:layout_rowWeight="1"/>
    </androidx.gridlayout.v7.widget.GridLayout>
    

    Note

    The new attributes are:

    • app:layout_columnWeight
    • app:layout_rowWeight
    • app:layout_rowSpan
    • app:layout_columnSpan