Sbd 1046 Pm

Common Controls

Name: John Doe Address:

911 Hollywood Elvd

Parent Container

Name container

Address Container

Figure 4-1. The user interface and layout of an activity

We will refer to this layout hierarchy as we discuss the sample programs. For now, know that the application has one activity. The user interface for the activity is composed of three containers: a container that contains a person's name, a container that contains the address, and an outer parent container for the child containers.

The first example, Listing 4-1, demonstrates building the user interface entirely in code. To try this out, create a new Android project with an activity named MainActivity and then copy the code from Listing 4-1 into your MainActivity class.

Listing 4-1. Creating a Simple User Interface Entirely in Code package pro.android;

import android.app.Activity;

import android.os.Bundle;

import android.view.ViewGroup.LayoutParams;

import android.widget.LinearLayout;

import android.widget.TextView;

public class MainActivity extends Activity {

private LinearLayout nameContainer; private LinearLayout addressContainer; private LinearLayout parentContainer;

/** Called when the activity is first created. */ ^Override public void onCreate(Bundle savedlnstanceState) {

super.onCreate(savedlnstanceState);

createNameContainer();

createAddressContainer();

createParentContainer();

setContentView(parentContainer);

private void createNameContainer() {

nameContainer = new LinearLayout(this);

nameContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.WRAP_CONTENT)); nameContainer.setOrientation(LinearLayout.HORIZONTAL);

TextView nameLbl = new TextView(this);

nameLbl.setText("Name: "); nameContainer.addView(nameLbl);

TextView nameValueLbl = new TextView(this); nameValueLbl.setText("John Doe");

nameContainer.addView(nameValueLbl);

private void createAddressContainer() {

addressContainer = new LinearLayout(this);

addressContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.WRAP_CONTENT)); addressContainer.setOrientation(LinearLayout.VERTICAL);

TextView addrLbl = new TextView(this);

addrLbl.setText("Address:");

TextView addrValueLbl = new TextView(this);

addrValueLbl.setText("911 Hollywood Blvd");

addressContainer.addView(addrLbl); addressContainer.addView(addrValueLbl);

private void createParentContainer() {

parentContainer = new LinearLayout(this);

parentContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.FILL_PARENT)); parentContainer.setOrientation(LinearLayout.VERTICAL);

parentContainer.addView(nameContainer); parentContainer.addView(addressContainer);

As shown in Listing 4-1, the activity contains three LinearLayout objects. As we mentioned earlier, layout objects contain logic to position objects within a portion of the screen. A LinearLayout, for example, knows how to lay out controls either vertically or horizontally. Layout objects can contain any type of view—even other layouts.

The nameContainer object contains two TextView controls: one for the label Name: and the other to hold the actual name (i.e., John Doe). The addressContainer also contains two TextView controls. The difference between the two containers is that the nameContainer is laid out horizontally and the addressContainer is laid out vertically. Both of these containers live within the parentContainer, which is the root view of the activity. After the containers have been built, the activity sets the content of the view to the root view by calling setContentView(parentContainer). When it comes time to render the user interface of the activity, the root view is called to render itself. The root view then calls its children to render themselves, and the child controls call their children, and so on, until the entire user interface is rendered.

As shown in Listing 4-1, we have several LinearLayout controls. In fact, two of them are laid out vertically and one is laid out horizontally. The nameContainer is laid out horizontally. This means the two TextView controls appear side by side horizontally. The addressContainer is laid out vertically, which means that the two TextView controls are stacked one on top of the other. The parentContainer is also laid out vertically, which is why the nameContainer appears above the addressContainer. Note a subtle difference between the two vertically laid-out containers: addressContainer and parentContainer. parentContainer is set to take up the entire width and height of the screen:

parentContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

And addressContainer wraps its content vertically:

addressContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

Now let's build the same user interface in XML (see Listing 4-2). Recall from Chapter 3 that XML layout files are stored under the resources (/res/) directory within a folder called layout. To try out this example, create an XML file named test.xml and place it under the layout folder. Create a new activity and override its onCreate() method. In the onCreate() method, call the base class's onCreate() method and then call setContentView(R.layout.test).

Listing 4-2. Creating a User Interface Entirely in XML <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- NAME CONTAINER -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">

<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Name:" />

<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="John Doe" />

</LinearLayout>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content">

<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Address:" />

<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="911 Hollywood Blvd." /> </LinearLayout>

</LinearLayout>

The XML snippet shown in Listing 4-2, combined with a call to setContentView(R.layout. test), will render the same user interface. The XML file is self-explanatory, but note that we have three container views defined. The first LinearLayout is the equivalent of our parent container. This container sets its orientation to vertical by setting the corresponding property like this: android:orientation="vertical". The parent container contains two LinearLayout containers, which represent the nameContainer and addressContainer.

Listing 4-2 is a contrived example. Notably, its doesn't make any sense to hard-code the values of the TextView controls in the XML layout. Ideally, we should design our user interfaces in XML and then reference the controls from code. This approach enables us to bind dynamic data to the controls defined at design time. In fact, this is the recommended approach.

Listing 4-3 shows the same user interface with slightly different XML. This XML assigns IDs to the TextView controls so that we can refer to them in code.

Listing 4-3. Creating a User Interface in XML with IDs <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- NAME CONTAINER -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">

<TextView android:id="@+id/nameText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@+string/name_text" />

<TextView android:id="@+id/nameValueText" android:layout_width="wrap_content"

android:layout_height="wrap_content" />

</LinearLayout>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content">

<TextView android:id="@+id/addrText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@+string/addr_text" />

<TextView android:id="@+id/addrValueText" android:layout_width="fill_parent"

android:layout_height="wrap_content" /> </LinearLayout>

</LinearLayout>

The code in Listing 4-4 demonstrates how you can obtain references to the controls defined in the XML to set their properties.

Listing 4-4. Referring to Controls in Resources at Runtime setContentView(R.layout.main);

TextView nameValue = (TextView)findViewById(R.id.nameValueText); nameValue.setText("John Doe");

TextView addrValue = (TextView)findViewById(R.id.addrValueText); addrValue.setText("911 Hollywood Blvd.");

The code in Listing 4-4 is straightforward, but note that we load the resource (by calling setContentView(R.layout.main)) before calling findViewById()—we cannot get references to views if they have not been loaded yet.

0 0

Post a comment