LAB

Android User Interface Layouts

Abstract

The primary purpose of this lab is to build a user interface and attach code that will execute in response to a button’s click event. In this lab, you will implement the same area calculator that you implemented in the second Java lab. But in this lab, you will:

  • Create another Android Application Project with a default activity
  • Understand the concept of a ViewGroup and Viewas a means to create event handlers.
  • Understand the details of the <LinearLayout> and <RelativeLayout
  • Understand the different ways to create event handlers
  • Work with various Android widgets

Key Terms

  • Absolute Layout: Using an AbsoluteLayout, child widgets are rendered one after another either horizontally or vertically.
  • Listener: A listener can be thought of as an event handler for a widget (control). It is an interface in the View class that contains a callback method. The callback method is called by the Android framework as the user interacts with the widget (such as clicks the button).
  • Relative Layout: Using a RelativeLayout, child widgets are rendered relative to the position of the parent window or another sibling widget.
  • View: Widgets on the screen with which a user interacts are derived from the View class. A View is contained in a ViewGroup.
  • ViewGroup: The screen itself and the widgets it contain are part of the ViewGroup class.
  • Widget: Android uses the term Widget for the visual objects seen by the user.

Introduction to the View and ViewGroup

Objects the user sees on the screen are built from either a View or a ViewGroup.

  • A ViewGroup is the base class for all layouts that contain other layouts and widgets, such as buttons or check boxes. Note the following about the View and ViewGroup classes:
  • A View is contained by a ViewGroup. Views are the widgets with which the user interacts. Through a View, you register event handlers, known in android as listeners. For example, the RelativeLayout and LinearLayout classes are derived from the ViewGroup class.
  • The ViewGroup class is derived from the View class.
  • The Buttton class is derived from the TextView class which is derived from the View class.

As you will progress through this tutorial you the View and ViewGroup classes are used frequently and better understand their operation and purpose.

Introduction to Sizes and Dimensions

All physical screens have a size and a resolution (dots per inch). Android supports what might be called density independence. You can define the size of layouts, widgets, and fonts using the following different units of measure.

Unit / Density independent / Description
px / No / Corresponds to the actual pixels on the screen.
In / Yes / Based on the physical size of the screen measured in inches.
mm / Yes / Based on the physical size of the screen measured in millimeters
pt / Yes / A point is 1/72 of an inch. Based on the physical screen size.
dp, dip / Yes / Density independent pixels are abstract units based on a 160 dpi (dots per inch)
dp = (width in pixels * 160) / screen density
sp / Yes / Scale independent units are similar to db units, but is also scaled based on the user’s font size preference.

The values appear as a layout attribute as follows. As always, attribute values are quoted.

android:layout_width="16dp"

In addition, sizes can be defined based on the size of another view. These sizes are describes using the following Android constants.

  • wrap_content causes the height or width to expand so that the values will fit in the visible region.
  • match_parent causes the View or ViewGroup to expand to that it fills the region of the parent window, which can be the screen itself. Note that fill_parent has been deprecated in favor of match_parent.

Gravity

Gravity is used to align widgets within a <LinearLayout> or text in a widget. There are two properties that work with gravity:

  • android:gravity sets the gravity (alignment) of the view’s content. It’s similar to the text-align property in CSS.
  • android:layout_gravity sets the gravity of the view itself. It is used to align the layout of a widget (view) relative to its container. It is only applicable to a <LinearLayout>.
    The figure from stackoverflow.com shows how gravity works. The gravity and layout_gravity attributes can have values of left, center_horizontal, right, and center.

Introduction to Layouts

The organization of the widgets (controls) drawn on a user interface (activity) is defined by its layout. A layout is an XML document using various XML namespaces. An activity can have many layouts. Android will automatically render one of these layouts (in the res/layout folder) depending on the device’s screen orientation and resolution.

The outermost element of a layout file is a class derived from the View or ViewGroup object. Android supports the following layouts:

  • <LinearLayout>: Using a <LinearLayout>, the child views (widgets) are rendered either horizontally or vertically. A <LinearLayout> can contain child <RelativeLayout> and <LinearLayout> elements.
  • <RelativeLayout>: Using a <RelativeLayout>, the child views (widgets) are rendered relative to each other, or relative to the parent window (layout). A <RelativeLayout> can contain child <RelativeLayout> and <LinearLayout> elements.
  • <ListView>: Items are displayed as vertical list. This layout will be discussed in subsequent labs.
  • <GridView>: Renders a two-column grid with cells. This layout will be discussed in subsequent labs.

Only the <LinearLayout> and <RelativeLayout> are discussed in this tutorial.

Each layout has attributes that determine size of the visible region known as the View.

  • The layout_width attribute defines the width of the layout. Its value can be a specific size or one of the contstant values discussed previously: “match_parent”,“wrap_content”.
  • The layout_height attribute works the same way but sets the height of the layout. It supports the same values as the layout_width attribute.

The following code fragment shows the declaration for a LinearLayou:.

LinearLayoutxmlns:android="

xmlns:tools="

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:orientation="vertical"

tools:context="com.example.androidlinearlayout.MainActivity"

The LinearLayout uses the android and tools namespaces.

The above code sample shows the setting of the layout_width and layout_height attributes. In the following example, the width and height of the layout will be the same as the screen itself (less the margins and padding)

Layouts can also have padding. Padding is the whitespace between the layout window and the parent window. It works the same way as the CSS padding attribute. Padding is set through the paddingBottom, paddingLeft, paddingRight, and paddingTop properties. By convention, these values are stored as resources in the dimens.xml resource file as follows. Both values are set to 16dp.

resources

<!-- Default screen margins, per the Android Design guidelines. -->

dimenname="activity_horizontal_margin"16dp</dimen

dimenname="activity_vertical_margin"16dp</dimen

</resources

The @dimen reference gets the value of a dimen resource. Although not used here, the marginBottom, marginLeft, marginRight, and marginTop properties define the whitespace outside the border.

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

Characteristics of a <LinearLayout>

<LinearLayout> renders its controls (widgets) either horizontally or vertically based on the value of the android:orientation property. Valid values are “horizontal” and “vertical”. To layout some controls horizontally and others vertically, you create <LinearLayout> elements inside of other <LinearLayout> elements.

When you use the <LinearLayout> only a few of the layout attributes are applicable to the child controls.

  • The android:layoutWidth property and android:layoutHeight properties operate as they do with the <LinerLayout> itself.
  • The android:gravity property is used to anchor the widget to the left or right side of its parent.

Characteristics of a <RelativeLayout>

<RelativeLayout> renders its widgets relative to each other, or relative to its parent. So the positioning attributes work much differently and are much more complicated.

Elements can be can positioned (anchored), relative to the parent view or a sibling based on the value of the following layout properties. When using relative layouts, some attributes are commonly used with each other. However, it’s possible to try to create layouts where the attributes conflict with each other. For example, it does not make sense to layout a control both above and below another control. We will not discuss what happens when rules collide.

The following list describes selected layout attributes and their effect on rendering:

  • android:layout_above causes this resource (widget) to be positioned (anchored) above the referenced resource.
  • android:layout_below causes this widget to be anchored below the referenced resource.
  • android:layout_alignStart causes this resource to be anchored at the starting position of the referenced widget.
  • android:layout_alignEnd causes this resource to anchored to the end of the referenced widget.
  • android:layout_toEndOf=”referenceControl” causes this resource to be aligned at the end of the reference control. This property is often used in place of the layout_alignEnd property to support right-to-left languages.
  • android:layout_centerHorizontal=”true|false” causes the resource to be centered horizontally within its container (parent view).

HANDS-ON ACTIVITY: Creating an Android Application with a Default Activity

In this part of the lab, you will create the same area and volume calculator that you did in the Java lab. However, this time, you will create the application in Android. In this section you will create the Android Application project, create the string and other resources, and define the layouts.

  1. Create a new Android Application project named AndroidLinearLayout. Use the settings shown in the following screen shot for the correct version numbers. Again, you might vary the version depending on your physical device and choice of emulators.

  2. Click Next. In the following dialog box, make sure the Createactivity check box is checked so that Eclipse will create a default activity.

  3. In the dialog box that displays the icons, accept the default options, and click Next. In the Create activity dialog box, select the Blank Activity.

  4. Click Next. In the final dialog box, use the default names for the activities. Click the Finish button to create the application.

At this point, you have created the same basic application that you created in the first Android lab. Next, you will create the resources that the widgets will use. In the first lab, you

HANDS-ON ACTIVITY: Creating String Resources

Recall that the strings.xml file in the res/values folder declares the application’s string resources (constants) for the application. In this lab, you will use string resources for the label and button prompts.

  1. Modify the res/values/strings.xml file so that it contains the following resources. Remember that these resources are case sensitive.

<?xml version="1.0" encoding="utf-8"?>

<resources>

<string name="app_name">AndroidLinearLayout</string>

<string name="action_settings">Settings</string>

<string name="length_prompt">Length:</string>

<string name="width_prompt">Width:</string>

<string name="height_prompt">Height:</string>

<string name="btnAreaText">Area</string>

<string name="btnVolumeText">Volume</string>

<string name="area_prompt">Area</string>

<string name="volume_prompt">Volume</string>

</resources>

HANDS-ON ACTIVITY: Creating a Relative Layout

In this set of steps, you will create the Layout for the activity.

  1. Open the file named res/layout/activity_main.xml in the folder. You can edit the code or try to use the visual tool. I sometimes find it easier to edit the XML directly. Remove the existing content (relative layout) and replace it with the following. Make sure to remove the default text control:
    LinearLayoutxmlns:android="

xmlns:tools="

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:orientation="vertical"

tools:context="com.example.androidlinearlayout.MainActivity"

  • The layout_width and layout_height properties are set such that the size of the view will be the size of the parent window, which is the screen.
  • The padding values are derived from dimen resource.
  • The orientation is set to vertical so the child widgets will be aligned from top to bottom.

Android User Interface Controls (Widgets)

Widgets (controls) appear nested inside of a layout. The following widgets are discussed in this tutorial.

  • The <TextView> widget displays text similar to a .NET Label control.
  • The <TextField> widget is comparable to the .NET TextBox. It provides a visible editable region. It can be configured to work with one line or many lines.
  • The <Button> widget is used to create a button that can be pressed or clicked. An action is performed in response to the click.
  • The <CheckBox> widget implements a check box that can be checked or unchecked.
  • The <RadioButton> widget works similar to a check box, but only one button can be checked from a group of buttons.

The <TextView> Control

The <TextView> control works similar to the .NET Label control. The following attributes are significant:

  • The android:labellFor attribute contains the name of the <TextField> or other control to which the control is associated. Setting the LabelFor attribute improves accessibility.
  • The android:layout_width and android:layout_height attributes define the size of the widget. The purpose of these attributes is the same as the attributes of the same name discussed previously. For example, you can use an explicit width, or constant values such as wrap_content.
  • The android:text attribute contains the literal text or string resource displayed in the widget’s visible area.

The following code segment shows the declaration of a <TextView>:

TextView

android:id="@+id/tvLength"

android:labelFor="@+id/txtLength"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/length_prompt"/>

  • In the above, the android:id is set to the new resource (“@+id/tvLength”). Again, the syntax @+id/ creates a new id resource.
  • The android:labelFor attribute is also set to the new resource (“@+id/txtLength”). Note that the + character creates the resource instead of referencing the resource. The resource is being created here because the declaration for the <EditText> named txtLength appears next in the XML declaration, so it has not been created yet.
  • The layout_width and layout_height attributes are set to match the content. The text appearing in the control is set to the existing string resource named length_prompt. Again, the @string syntax references an existing string resource declared in the res/values/strings.xml file.

The <EditText> Control

The <EditText> control is used to create an editable text box having the following attributes:

  • The android:layout_width and android:layout_height properties have the same purpose as they do with other controls. They define the size of the control instance.
  • The android:text attribute stores the visible text. String resources should be used in place of literal values.
  • The android:inputType attribute restricts the allowable input to particular patterns. The value numberSigned restricts the allowable input values to positive or negative numbers. The following link lists all of the input types:

EditText

android:id="@id/txtLength"

android:layout_width="match_parent"

android:layout_height="wrap_content"
android:inputType="numberSigned"

/>

Using code, you can get or set the text stored in an <EditText> resource.

  • The getText method gets the text stored in the resource. The method accepts no arguments.
  • The setText method accepts one argument, a string) and updates the text stored in the resource.

The following code segment shows how to reference an <EditText> resource and get and set the textual value.

final EditText txtDemo;
txtDemo = (EditText) findViewByID(R.id.txtDemo)
txtDemo.setText(“Hello”);
String s = txtDemo.getText.toString();

  • The first of the above statements declares a variable named txtDemo having a data type EditText. Widgets have the same name in a layout file (<EditText>) as they do in the Java code file.
  • Remember that every visible widget is considered a View. The findViewById method of the Activity class gets a View instance. The method’s argument contains a reference to the widget is the id attribute in the R file. txtDemo.setText stores the string, passed as an argument, in the View’s visible area. The final statement shows how to get the string contents by calling the getText() method.

The following code segment shows a segment of the R file to illustrate the connection between the Java Code and the element declaration in the R file.

public static final class id {
public static final int txtDemo=0x7f080003;
}

The <Button> Control

The <Button> control implements a clickable button, for which you can handle a click event. The following code segment shows the layout declaration for a <Button>:

Button

android:id="@+id/btnArea"

style="?android:attr/borderlessButtonStyle"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/btnAreaText"

/>

  • Since the id resource is declared (+@id/btnArea), the object can be referend from the R file. Again, the +@id/ fragment declares a new resource.
  • The android:layout_width and android:layout_height properties have the same purpose as they do with other widgets. They define the size of the control instance. In the above, the width and height are sized based on the size of the content (wrap_content).
  • The android:text attribute contains the text appearing in the control’s visible region. Again, the text is set using the existing string resource named btnAreaText. (@string/btnAreaText)

At this point, you have information needed to create the activity’s widgets in the layout.