Sie sind auf Seite 1von 11

Advanced User Interfaces - Tabs

This lesson will concentrate on working with Tabs, Menus and Dialogs available within the Android OS.

Begin by creating a new project in Eclipse by selecting the File menu, then the New option, then Project.
Highlight Android Project in the New Project wizard, and click Next.

Provide the following information:

Project name: A2L1AdvancedUI


Create new project in workspace should be selected.
Built Target: Android 4.0.3 (You can use any OS version 2.1 and higher for this.)
Application name: AdvancedUI
Package name: lastname.firstname. AdvancedUI (substitute lastname.firstname with your last name
and first name – no spaces, apostrophes or dashes.)
Create Activity should be checked, and AdvancedUIActivity should be the prompt’s text.
Min SDK Version: 7 (This will make the icons compatible with all versions of Android 2.1 and higher.)

Using the Project Explorer, expand the project structure. We will be working in the src
/your.package.name/ folder, the res/drawable-hdpi/ folder, and the res/layout/ folder today.

1
Let’s begin by importing the graphical assets, which will be used throughout this lesson, into the
drawable-hdpi folder. Open the app_icons.zip file associated with this lesson, and extract all of the
graphics found there. Copy and paste them into the drawable-hdpi folder. Technically, we should have
versions of those images for each of the resolutions (hdpi = high density, mdpi = medium density, and
ldpi = low density), but for this example, we’re simply going to concentrate on the HDPI versions.

2
The graphics consist of icons that we will use for tabs and menu choices within our project, as well as a
graphics (android.png) that will be used as part of our custom dialog box.

After the import, your drawable-hdpi folder should look like this:

Right-click on the drawable-hdpi folder in Project Explorer, and select Refactor, then Rename. Rename
the folder to be drawable-hdpi-v5.

This step is necessary in order to make our tabs compatible with all versions of Android, specifically 2.1
and higher. For more information, you can review this article:
http://developer.android.com/guide/practices/ui_guidelines/icon_design_tab.html

Now, we can work on our main.xml file to set up the UI. Begin by opening the main.xml file found in
res/layout folder. Once opened, remove the “Hello World, AdvancedUIActivity!” TextView that appears
in the editor. You can do this using the XML view or the Graphical Layout.

Now, using the Graphical Layout view, drag out a TabHost view (found under Composite) onto the
activity screen. Your layout should now look like this:

3
Switch over to the XML view and review the structure. Notice that you now have a TabHost node, then
a LinearLayout, followed by a TabWidget, and a FrameLayout. Inside the FrameLayout are three
LinearLayouts, which represent each of the tabs that you want to display within your interface. Each
tab gets its own LinearLayout component.

4
First, modify the TabHost node, and change its ID property to be “@+id/tabhost”, instead of
“@android:id/tabhost”. This will make it available to us in code.

<TabHost
android:id="@+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >

Next, to keep things simple, we’re going to add some very basic UI elements to each of the tabs. Modify
the three tabs LinearLayouts to look like this (add the items highlighted in yellow):

5
<LinearLayout
android:id="@+id/tab1"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1" >
</Button>

<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 2" >
</Button>
</LinearLayout>

<LinearLayout
android:id="@+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<Button
android:id="@+id/button3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 3" >
</Button>

<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 4" >
</Button>
</LinearLayout>

<LinearLayout
android:id="@+id/tab3"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<AnalogClock
android:id="@+id/analogClock1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

</LinearLayout>

6
You’ve now added two buttons to Tab 1 and two buttons to Tab 2, and an Analog Clock to Tab 3. Save
the main.xml file.

Before we can preview our efforts, we need to set up the tabs within our code as well. And before we
can do that, we need to define the icons that each tab will use. This is accomplished by creating
Selector xml files, which we’ll store in the drawable-hdpi folder.

Select the drawable-hdpi folder in the Package Explorer, and then select the New Android File option
on the main menu.

Type in icon1.xml in as the File name, and choose selector as the Root Element, then click finish.

7
Enter the following code (highlighted in yellow) for your icon1.xml file. You are setting up a normal and
selected states for ICON1, which will be used by Tab 1. Basically, in its unselected state, the icon will
look like this:

(icon1_unselected.png)

While, when the tab is selected, it will look like this:

(icon1_selected.png)

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


<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- SELECTED STATE -->
<item android:drawable="@drawable/icon1_selected"
android:state_selected="true" android:state_pressed="false" />
<!-- UNSELECTED STATE -->
<item android:drawable="@drawable/icon1_unselected" />
</selector>

Save the icon1.xml file, then repeat the entire process to create icon2.xml and icon3.xml. Use the code
below for each.

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


<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- SELECTED STATE -->
<item android:drawable="@drawable/icon2_selected"
android:state_selected="true" android:state_pressed="false" />
<!-- UNSELECTED STATE -->
<item android:drawable="@drawable/icon2_unselected" />
</selector>
icon2.xml

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


<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- SELECTED STATE -->
<item android:drawable="@drawable/icon3_selected"
android:state_selected="true" android:state_pressed="false" />
<!-- UNSELECTED STATE -->
<item android:drawable="@drawable/icon3_unselected" />
</selector>

icon3.xml

8
Note that Eclipse may automatically create a “drawable” folder for you, instead of using the drawable-
hdpi folder that you already have. This is OK, as the icon selector definitions can be used by all
resolutions.

Now, open the AdvancedUIActivity.java file. It’s time to add the code necessary to set up our tabs.

Modify the onCreate event to look like this (add the code highlighted in yellow):

public void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);
setContentView(R.layout.main);

TabHost tabs = (TabHost) findViewById(R.id.tabhost);

tabs.setup();

TabHost.TabSpec spec = tabs.newTabSpec("tag1");

spec.setContent(R.id.tab1);
spec.setIndicator("Tab 1", getResources().getDrawable(R.drawable.icon1));
tabs.addTab(spec);

spec = tabs.newTabSpec("tag2");
spec.setContent(R.id.tab2);
spec.setIndicator("Tab 2", getResources().getDrawable(R.drawable.icon2));
tabs.addTab(spec);

spec = tabs.newTabSpec("tag3");
spec.setContent(R.id.tab3);
spec.setIndicator("Tab 3", getResources().getDrawable(R.drawable.icon3));
tabs.addTab(spec);
}

The above code basically locates our tabhost view in XML, and configures each of the tabs to use the
appropriate icon and text. We first use findViewByID to locate the tabhost element, which we store in
the tabs variable. Next, we put tabs into setup mode, and create a tab specification or “spec”. For each
tab, we specify the text “Tab 1”, “Tab 2”, and “Tab 3”, and the appropriate selector icon (icon1, icon2, or
icon3 xml files, referenced as drawables).

We also need to tell each tab, which content to display. This is done with the setContent method, which
attaches each tab to the UI we defined in our main.xml file.

Save the file, and run your project. You should see the following results:

9
All three tabs should display unique content, and you should be able to see the tab icons that are
displayed within each of the tabs.

As you can see, the code and GUI development required to add tabs are minimal, and provide end users
and developers with many benefits. You’re now able to split up your screens into logical functions, yet
all can be accessed from within the same Activity.

A note about Ice Cream Sandwich – The tabs we created above work great across all Android versions
2.1 and higher. However, they degrade the UI style for ICS (Android OS Version 4). The newer style
allows you to define text or an icon for a tab, but not both. The visuals are also vastly different than the
example you have created here, but the code doesn’t change all that much.

To test this out for yourself, do the following. You must be using an emulator running Android 4 or
higher to see the results.

Modify the AndroidManifiest.xml file in your project, and change the minSdkVersion from 7 to 15.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="tushinsky.alex.AdvancedUI"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="15" />

<application
android:icon="@drawable/ic_launcher"
d id l b l "@ i / "

Next, modify the code in OnCreate. You can change the spec.setIndicator to use null for the tab’s text
(“Tab 1”, “Tab 2”, or “Tab 3”) to see the icons, or leave the text in place to see the text, but not the icon.

10
You can also mix and match, as I did below. In this example, you will see the icon for the first and
second tabs, and text for the third.

tabs.setup();

TabHost.TabSpec spec = tabs.newTabSpec("tag1");

spec.setContent(R.id.tab1);
spec.setIndicator(null,getResources().getDrawable(R.drawable.icon1));
tabs.addTab(spec);

spec = tabs.newTabSpec("tag2");
spec.setContent(R.id.tab2);
spec.setIndicator(null, getResources().getDrawable(R.drawable.icon2));
tabs.addTab(spec);

spec = tabs.newTabSpec("tag3");
spec.setContent(R.id.tab3);
spec.setIndicator("Tab 3", getResources().getDrawable(R.drawable.icon3));
tabs.addTab(spec);

The results, as you can see are drastically different than before. Please keep in mind that because you
changed the minimum required version, this project won’t run on any device now that isn’t running ICS.
Be sure to change the minimum requirements back to version 7 in the manifest file, before you
continue.

11