Android TableLayout is used to create grids on the screen. It’s one of the ViewGroup classes, which is used to create a table on the screen.
Android TableLayout
As the name suggests, TableLayout is used to create a layout in the form of rows and columns. It’s similar to tables or the excel sheets.
The TableLayout container consists of child views in the form of tablerow
.
A TableRow default layout_width is match_parent and layout_height is wrap_content.
We can define child views inside the TableRow element. Each of the child view is similar to a cell in the excel sheet.
Defining TableLayout in XML
The following example show how to define a TableLayout in the layout XML file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
<?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="https://www.journaldev.com/136/@mipmap/ic_launcher" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="https://www.journaldev.com/136/@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> |
Output:
- The default alignment of TableRow elements is 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 have to define the size of the columns to avoid overflow outside the screen.
Sizing Table Columns in Android TableLayout
The 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 requirements.
- android:stretchColumns is used to stretch the columns.
- android:shrinkColumns is used to shrink the columns.
- android:collapseColumns is used to collapse the columns.
The 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?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. The first and second columns would be empty.
1. 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<?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="https://www.journaldev.com/136/@mipmap/ic_launcher" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="https://www.journaldev.com/136/@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> |
Output:
So the stretchColumns would take as much space as it is taken in the row with the most number of 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.
2. android:shrinkColumns
This works in the opposite way of android:stretchColumns. It shrinks the columns to give you free space.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
<?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="https://www.journaldev.com/136/@mipmap/ic_launcher" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="https://www.journaldev.com/136/@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> |
Output:
As you see our first issue in which the columns went beyond the screen is fixed. The shrinkColumns shrinks each column width specified in the attribute by the same amount. Since we’ve set *, it shrinks all by the same. The shrinkColumns attribute is used to fit ALL cells in the screen.
3. android:collapseColumns
The android:collapseColumns is used to collapse the specified columns. It means the specified columns would be invisible in the TableRow.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
<?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="https://www.journaldev.com/136/@mipmap/ic_launcher" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="https://www.journaldev.com/136/@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 Table Layout Weights
We can specify the weights on the TableRow to set the percentage height of the TableRow with respect to the TableLayout.
The android:weightSum
needs to be set on the TableLayout and android:layout_weight
on each of the TableRows.
How to Create TableLayout Programmatically?
We can create a TableLayout as well as TableRows programmatically. In the following application, we’ll create a TableLayout that will dynamically create a Grid of X rows and Y Columns.
The activity_main.xml layout looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
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.
Output: