Android TableLayout Using Kotlin

Filed Under: Android

In this tutorial, we’ll be discussing TableLayouts which are often used in the form of grids.

Android TableLayout

As the name suggests a TableLayout is used to create a layout in the form of rows and columns. Just like an excel sheet.
A TableLayout container consists of child views of the form of
A TableRow by default has the layout_width as match_parent and layout_height as wrap_content.
Inside the TableRow we can define our child views that. Each child view inside the TableRow is like a cell.
Similar to LinearLayouts, we can use layout weights on the TableRows

Following example depicts a TableLayout.


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

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 1 C 1" />


        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 1 C 2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 1 C 3" />
    </TableRow>

    <TableRow android:gravity="center">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />
    </TableRow>

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 3 C 1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 3 C 2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 3 C 3" />


        <Button
            
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 3 C 4" />


        <Button
            android:background="@android:color/holo_red_dark"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="R 3 C 5" />
    </TableRow>
</TableLayout>

The output looks like this:
android-kotlin-tablelayout-xml-1

Each TableRow aligns its elements by default to the left.
In the middle TableRow we’ve set the gravity as center
The TableLayout aligns its Rows to the top.
The third TableRow consists of 5 columns and the fifth column goes out of the screen.

How to fix this?
We need to size the columns and that’s exactly what we’ll see in the next section.

Sizing Table Columns

Number of columns in the TableLayout is equal to the highest number of cells in a TableRow.
The width of a column is defined by the row with the widest cell in that column.
However, we can set the columns to stretch, shrink or collapse as per our need.

  • android:stretchColumns is used to stretch the columns.
  • android:shrinkColumns is used to shrink the columns.
  • android:collapseColumns is used to collapse the columns.

Columns are present inside a TableRow.
Every TableRow has the same number of columns = Highest number of columns.
Column numbers start from 0,1,2….
Inside the cell, we can assign the column number using the layout_column attribute


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

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 1 C 1" />


        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 1 C 2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 1 C 3" />
    </TableRow>

    <TableRow android:gravity="center">
        

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:layout_column="3"
            android:text="R 2 C 1" />
    </TableRow>

</TableLayout>

The second TableRow has the Button placed in the third column, rightmost. The first and second columns would be empty.

android:stretchColumns

The column number entered would take up the available free space in the TableRows, if any.
android:stretchColumns = 0 means the first column takes up the free space.
android:stretchColumns = 0,1 means the first and second columns take up the free space.
android:strechColumns =”*” means all columns would take up the free space.


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

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 1 C 1" />


        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 1 C 2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 1 C 3" />
    </TableRow>

    <TableRow android:gravity="center">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />
    </TableRow>

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 3 C 1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 3 C 2" />

    </TableRow>
</TableLayout>

The output looks like this:
android-kotlin-table-layout-stretched

Without the stretchColumns attribute in the above code, it’ll look like:
android-kotlin-table-layout-not-stretched

So stretchColumns would take as much space it is taken in the row with most columns.
If any of the TableRow has cells that take up ALL the space, then NONE of the columns in NONE of the TableRows would be stretched.

android:shrinkColumns
This works just the opposite of android:stretchColumns. It shrinks the columns to give you free space.


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

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:layout_column="0"
            android:text="R 1 C 1" />


        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 1 C 2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 1 C 3" />
    </TableRow>

    <TableRow android:gravity="center">

        <ImageView
            android:layout_column="0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />
    </TableRow>

    <TableRow>

        <Button
            android:layout_column="0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 3 C 1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 3 C 2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 3 C 3" />


        <Button

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 3 C 4" />


        <Button
            android:background="@android:color/holo_red_dark"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="R 3 C 5" />


        <Button
            android:background="@android:color/holo_green_dark"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="R 3 C 6" />
    </TableRow>
</TableLayout>

Following is the output:
android-kotlin-table-layout-shrinked

As you see our first issue in which the columns went beyond the screen is fixed.
shrinkColumns shrinks each column width specified in the attribute by the same amount. Since we’ve set *, it shrinks all by the same.
shrinkColumns is used to fit ALL cells in the screen.

android:collapseColumns
android:collapseColumns is used to collapse the columns specified. It means the specified columns would be invisible in the TableRow.

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:collapseColumns="1,4,5"
    android:layout_height="match_parent">

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:layout_column="0"
            android:text="R 1 C 1" />


        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 1 C 2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 1 C 3" />
    </TableRow>

    <TableRow android:gravity="center">

        <ImageView
            android:layout_column="0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />
    </TableRow>

    <TableRow>

        <Button
            android:layout_column="0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 3 C 1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 3 C 2" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="R 3 C 3" />


        <Button

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_green_dark"
            android:text="R 3 C 4" />


        <Button
            android:background="@android:color/holo_red_dark"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="R 3 C 5" />


        <Button
            android:background="@android:color/holo_green_dark"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="R 3 C 6" />
    </TableRow>
</TableLayout>

The first, fifth and sixth columns are collapsed.
android-kotlin-table-layout-collapsed

Layout Weights

Just like LinearLayouts, we can specify the weights on the TableRow to set the percentage height of the TableRow with respect to the TableLayout.
android:weightSum needs to be set on the TableLayout and android:layout_weight on each of the TableRows.

Create TableRows Programmatically

We can create a TableLayout as well as TableRows programmatically.
In the following application, we’ll create a TableLayout which will dynamically create a Grid of X rows and Y Columns as specified.

The activity_main.xml layout looks like this:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

The code for the MainActivity.kt class is given below:


package net.androidly.androidlylayouts


import android.app.ActionBar
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TableLayout
import android.widget.TableRow
import kotlinx.android.synthetic.main.activity_main.view.*
import android.widget.TextView


class MainActivity : AppCompatActivity() {

    val ROWS = 10
    val COLUMNS = 5
    val tableLayout by lazy { TableLayout(this) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        textView.text = "ROWS : $ROWS COLUMNS: $COLUMNS"


        val lp = TableLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        tableLayout.apply {
            layoutParams = lp
            isShrinkAllColumns = true
        }


        createTable(ROWS, COLUMNS)


    }

    fun createTable(rows: Int, cols: Int) {

        for (i in 0 until rows) {

            val row = TableRow(this)
            row.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT)

            for (j in 0 until cols) {

                val button = Button(this)
                button.apply {
                    layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
                            TableRow.LayoutParams.WRAP_CONTENT)
                    text = "R $i C $j"
                }
                row.addView(button)
            }
            tableLayout.addView(row)
        }
        linearLayout.addView(tableLayout)
    }

}

In the for loop until creates a range of indexes that doesn’t include the right hand side number.

The output of the above application in action is given below:

android-kotlin-table-layout-dynamic-output

This brings an end to this tutorial. You can download the AndroidlyLayouts Project from the link below.

Comments

  1. Elisei says:

    Hi bro, how can I go through this Table (last)

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages