Search code examples
androidbuttonresolutiondpi

craeate grid of buttons independent from resolution of device


I want to create a grid of Buttons in my android app. The problem is, when I test this on low resolution devices, some Buttons are displayed off the screen. How can I fix that?

This is the layout I am using:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:columnCount="4"
    android:orientation="horizontal">

    <Button
        android:text=""
        android:id="@+id/b0"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b1"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b2"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b3"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b4"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b5"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b6"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b7"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b8"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b9"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b10"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b11"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b12"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b13"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b14"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <Button
        android:text=""
        android:id="@+id/b15"
        android:padding="20dp"
        android:layout_margin="10dp" />

    <TextView
        android:id="@+id/text1"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:textSize="30sp"
        android:text="  Taget:-" />

    <TextView
        android:id="@+id/tar"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:textSize="30sp"
        android:text="" />

    <TextView
        android:id="@+id/text2"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:textSize="30sp"
        android:text="  Current:-" />

    <TextView
        android:id="@+id/cur"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:textSize="30sp"
        android:text="" />

    <TextView
        android:id="@+id/text3"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:textSize="20sp"
        android:text="  TimeLeft:-" />

    <TextView
        android:id="@+id/tim"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:textSize="20sp"
        android:text="" />


</GridLayout>

Solution

  • When using a GridLayout you need to specify where exactly you want the Views to be positioned and how big they are supposed to be. Try something like this:

    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnCount="2"
        android:rowCount="2"
        android:orientation="horizontal">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="0"
            android:layout_row="0"
            android:layout_columnSpan="2"
            android:layout_rowSpan="2" />
    
        ...
    
    </GridLayout>
    

    To define how many rows and columns there are use these two attributes on the GridLayout:

    • android:columnCount
    • android:rowCount

    You can define the position of a View inside the GridLayout with these two attributes:

    • android:layout_column
    • android:layout_row

    And you can define how many rows or columns a View spans with these two attributes:

    • android:layout_rowSpan
    • android:layout_columnSpan

    Please note that the GridLayout was only added with API level 14! If you want to use the GridLayout in earlier versions you need to use the GridLayout from the support library:

    <android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        ...    
    
    </android.support.v7.widget.GridLayout>
    

    Also note that you ARE NOT supposed to hardcode a fixed size for each Button. Set height and width to wrap_content, the GridLayout will take care of setting the size of the Buttons.

    You can decrease the amount of columns you display by using a resource selector:

    For example define this in res/values/dimens.xml so smaller devices use only two columns:

    <dimen name="column_count">2</dimen>
    

    And in res/values-w350dp/dimens.xml you define the same dimen resource with a bigger value:

    <dimen name="column_count">3</dimen>
    

    The w350dp means that all device which have a width bigger than 350dp use 3 columns instead of the default 2.

    To make this work you of course need to set this dimen resource as the columnCount on your GridLayout:

    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnCount="@dimen/column_count"
        android:rowCount="2"
        android:orientation="horizontal">
    
        ...
    
    </GridLayout>