Chapter 2. A New Layout – GridLayout

A new layout is introduced with Android Ice Cream Sandwich known as the GridLayout. This layout is an optimized layout and could be used instead of LinearLayout and RelativeLayout. This chapter shows how to use and configure GridLayout.

The topics covered in this chapter are as follows:

  • Why to use GridLayout
  • Adding a GridLayout
  • Configuring GridLayout

GridLayout

GridLayout is a layout that divides its view space into rows, columns, and cells. GridLayout places views in it automatically, but it is also possible to define the column and row index to place a view into GridLayout. With the span property of cells, it is possible to make a view span multiple rows or columns. The following code block shows a sample layout file using a GridLayout layout:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/GridLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2"
android:orientation="horizontal" android:rowCount="2">

<TextView
android:id="@+id/textView1"
android:text="Cell 1,1"
android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
android:id="@+id/textView2"
android:text="Cell 1,2"
android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
android:id="@+id/textView3"
android:text="Cell 2,1"
android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
android:id="@+id/textView4"
android:text="Cell 2,2"
android:textAppearance="?android:attr/textAppearanceLarge" />

</GridLayout>

When this layout XML is viewed in the emulator it will look like the following screenshot:

GridLayout

In this layout XML file, we placed four TextView components with the texts Cell 1,1, Cell 1,2, Cell 2,1, and Cell 2,2. With the GridLayout orientation set to horizontal and the columnCount and rowCount properties set to 2, GridLayout firstly places items automatically to the first row, and when the number of items reaches columnCount; it starts placing items in the second row.

The first thing you will notice in this layout is that TextView components don't have layout_width and layout_height properties. These properties are not used because GridLayout uses the layout_gravity property for determining the size of cells instead of layout_width and layout_height properties. Normally the gravity property is used to align the content of a view, but in GridLayout it is used for a different purpose. The available gravity constants include left, top, right, bottom, center_horizontal, center_vertical, center, fill_horizontal, fill_vertical, and fill.

In GridLayout, you can explicitly define the cell that a view will be placed in by specifying the index of the column and row. If the index is not specified, GridLayout will automatically place the views to the first available position according to the orientation of the GridLayout layout.

Why to use GridLayout

LinearLayout and RelativeLayout are the most common layouts used in user interface design in Android. For simple user interfaces they are a good choice but when the user interface gets complicated, the use of nested LinearLayout tends to increase. Nested layouts (of any type) can hurt performance, and furthermore nested LinearLayout deeper than 10 may cause a crash in your application. Thus, you should either avoid using too many nested LinearLayout blocks or you should use RelativeLayout in order to decrease nested LinearLayout blocks. Another drawback of these layouts for complicated user interfaces is the difficulty in readability. It is difficult to maintain nested LinearLayout or RelativeLayout layouts that have many views. It is a good choice to use GridLayout in these cases. Too many nested LinearLayouts could be avoided by using GridLayout. Furthermore, it is much easier to maintain GridLayout. Many of the user interfaces that use LinearLayout, RelativeLayout, or TableLayout can be converted to GridLayout where GridLayout will provide performance enhancements. One of the major advantages of GridLayout over other layouts is that you can control the alignment of a view in both horizontal and vertical axes.

Adding a GridLayout

In this section we are going to migrate an Android application from LinearLayout to GridLayout. The layout's XML code of the application with LinearLayout is shown in the following code block:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" android:background="#ffffff">
<!-- we used 3 nested LinearLayout-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<!—LinearLayout that contains labels-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username:"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#000000" android:layout_gravity="right"/>

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password:"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#000000" />
</LinearLayout>
<!—Linearlayout that contains fields-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/borders_bottom_right"
android:ems="10" >

</EditText>

<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/borders_bottom_right"
android:ems="10" />
</LinearLayout>
</LinearLayout>


<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK" android:layout_gravity="center_horizontal"/>

</LinearLayout>

The drawable borders_bottom_right background used in the preceding layout file is shown in the following code block:

<?xml version="1.0" encoding="utf-8"?>
  <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
    <shape android:shape="rectangle">
    <stroke android:width="1dp" android:color="#FFFFFF" />
    <solid android:color="#000000" />
    </shape>
  </item>
  </layer-list>

The screen will look like the following:

Adding a GridLayout

As you can see in the layout XML code, we used three nested LinearLayout instances in order to achieve a simple login screen. If this screen was designed with GridLayout, the XML code of the layout would look like the following code block:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#ffffff"
  android:columnCount="2"
  android:orientation="horizontal" >

  <TextView
    android:id="@+id/textView1"
    android:layout_gravity="right"
    android:text="Username:" android:textColor="#000000"/>

  <EditText
  android:id="@+id/editText1"
  android:ems="10" android:background="@drawable/borders"/>

  <TextView
    android:id="@+id/textView2"
    android:text="Password:"
    android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#000000"/>

  <EditText
    android:id="@+id/editText2"
    android:ems="10" android:background="@drawable/borders">

  </EditText>

  <Button
    android:id="@+id/button1"
    android:layout_columnSpan="2"
    android:text="Button" android:layout_gravity="center_horizontal"/>

</GridLayout>

We set the columnCount property to 2 because we have a TextView component and an EditText component in a row. After that we placed the views and didn't specify the row or column index. GridLayout placed them automatically according to orientation and columnCount. We set the layout_columnSpan property to 2 in order to make the button span two columns. With the layout_gravity property we made the button appear in the center of the row. As you can see in the XML code of the layout, it is very simple and easy to design the same screen with GridLayout. Furthermore, alignments are much easier with GridLayout and this code has better readability.

GridLayout has been available since API Level 14, so the minimum SDK property in the AndroidManifest.xml file should be set to 14 or greater as shown in the following code line:

<uses-sdkandroid:minSdkVersion="14" />

Configuring GridLayout

Firstly, we will write a sample GridLayout XML code and then we will use this code as a base for other examples. The XML code of the sample layout will look like the following code block:

<?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_horizontal"
android:columnCount="3"
android:rowCount="3" >

<TextView
android:text="[1,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[1,2]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[1,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[2,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[2,2]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[2,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,2]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

</GridLayout>

Using the preceding code block the screen will look like the following:

Configuring GridLayout

As you can see in the layout XML code, TextView components are placed without indices and they are automatically positioned in GridLayout according to orientation, columnCount, and rowCount. Now we will set the index number of [1, 3] to [2, 1]. The layout XML code should look like the following:

<?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_horizontal"
android:columnCount="3"
android:rowCount="3" >

<TextView
android:text="[1,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[1,2]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>
<!-- set the row and column index with layout_row and layout_column
properties-->
<TextView
android:text="[1,3]"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_row="1" android:layout_column="1"/>

<TextView
android:text="[2,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[2,2]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[2,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,2]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

</GridLayout>

The screen should look like the following:

Configuring GridLayout

As you see in the layout XML code (the highlighted part), we set the row and column index with layout_row and layout_column properties. The index is zero-based, thus the TextView component with text [1, 3] is placed to the second row and second column. The interesting part here is that the TextView component with text [2, 1] is placed after [1, 3]. This is because [2, 1] doesn't have an index and GridLayout continues positioning after [1, 3]. That is GridLayout looks for the first available position after the last placed view. Another noteworthy thing is that after shifting indices, the row count increased to 4 although we set the row count to 3. GridLayout doesn't throw exception in such cases.

In the following sample, we will swap [1, 2] and [2, 2].The layout XML code should look like the following:

<?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_horizontal"
android:columnCount="3"
android:rowCount="3" >

<TextView
android:text="[1,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>
<!-- set layout_row of [1, 2] to 1-->
<TextView
android:text="[1,2]"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_row="1"/>
<!-- set layout_row of [1, 2] to 1-->
<TextView
android:text="[1,3]"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_row="0"/>

<TextView
android:text="[2,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>
<!-- set the layout_row of [2, 2] to 0 and layout_column to 1-->
<TextView
android:text="[2,2]"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_row="0" android:layout_column="1"/>
<!-- set layout_row of [2, 3] to 1 in order to make it appear after [1,2]'s
new position-->
<TextView
android:text="[2,3]"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_row="1"/>

<TextView
android:text="[3,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,2]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

</GridLayout>

The screen should look like the following:

Configuring GridLayout

As you see in the layout XML code, we firstly set layout_row of [1, 2] to 1. By this way, it will appear in place of [2, 2]. Then we have to set layout_row of [1, 3] to 0 and layout_column to 2, because the cursor position of GridLayout was changed by setting the index of [1, 2]. If we don't change the index of [1, 3], it will be placed after the [1, 2] index's new position. After that, in order to make [2, 2] appear in position of [1, 2], we set the layout_row of [2, 2] to 0 and layout_column to 1. Lastly, we have to set layout_row of [2, 3] to 1 in order to make it appear after [1, 2] index's new position. It seems a little complex to configure views in GridLayout, but if you try it in an emulator, you will see that it isn't that difficult.

In the following sample code, we will delete [2, 2] and make [1, 2] to span two rows. The layout XML code look like the following:

<?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_horizontal"
android:columnCount="3"
android:rowCount="3" >

<TextView
android:text="[1,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>
<!-- set layout_rowSpan property of [1,2] to 2. By this way [1,2] will
cover 2 rows.-->
<TextView
android:text="[1,2]"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_rowSpan="2" android:layout_gravity="fill"
android:gravity="center"/>

<TextView
android:text="[1,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[2,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[2,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,1]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,2]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:text="[3,3]" 
android:textAppearance="?android:attr/textAppearanceLarge"/>

</GridLayout>

Using the preceding code block we get the following screen:

Configuring GridLayout

As you can see in the layout XML code, we deleted the cell [2,2] and set the layout_rowSpan property of [1,2] to 2. By this way, [1,2] will cover two rows. We set the layout_gravity property to fill in order to make it fill the space of two rows. Then we set the gravity property to center in order to make the content of the TextView component to align to the center of space that it covers.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
35.171.45.182