Mobility

Android tabs hurt my head

The official way of handling tabs in Android now relies on "a trick." William Francis makes the case for why he demonstrates the "old" way of doing tabs.

1.       Create a new Android project targeted at SDK 1.6 or above.

2.       In the /res/layout folder create an XML layout for the main activity.

main.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/tabhost"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:id="@android:id/tabs"/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0"
android:id="@android:id/tabcontent"/>
</LinearLayout>
</TabHost>

3.       You will need a simplistic layout for both of the activities our tab activity will host; both of these activities go in the /res/layout folder.

activity_1.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"
android:gravity="center"
android:background="#ff0000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="26sp"
android:textStyle="bold"
android:textColor="#ffffff"
android:text="This is one activity."/>
</LinearLayout>
activity_2.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"
android:gravity="center"
android:background="#0000ff">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="26sp"
android:textColor="#ffffff"
android:text="And this is another."/>
</LinearLayout>

4.       Add two lines to the generated AndroidManifest.xml file — one for each of the activities the tab widget will host. These activities get defined in the application node of the manifest as shown below.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.authorwjf"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".FirstActivity" />
<activity android:name=".SecondActivity" />
</application>
<uses-sdk android:minSdkVersion="4" />
</manifest>

5.       In your /src folder, you should create two new classes that correspond to the two classes we added to the manifest.

FirstActivity.java
package com.authorwjf;
import android.app.Activity;
import android.os.Bundle;
public class FirstActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_1);
}
}
SecondActivity.java
package com.authorwjf;
import android.app.Activity;
import android.os.Bundle;
public class SecondActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
}
}

6.       Implement the Main.java class. In the class, you create a new tab host, and then create tab specs for each tab and its corresponding activity. Those tab specs are added to the tab host.

Main.java
package com.authorwjf;
import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
public class Main extends TabActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost th = (TabHost)findViewById(android.R.id.tabhost);
TabSpec ts1 = th.newTabSpec("tab_id_1");
TabSpec ts2 = th.newTabSpec("tab_id_2");
ts1.setIndicator("First Tab").setContent(new Intent(this,FirstActivity.class));
ts2.setIndicator("Second Tab").setContent(new Intent(this,SecondActivity.class));
th.addTab(ts1);
th.addTab(ts2);
}
}
When you run the app, you'll find it's not very impressive (Figure A and Figure B). That's okay because it was meant to be clear and easy to digest. I hope in that regard you'll agree this tutorial is a success. Figure A

Figure B

For those of you who still question my decision not to write this Android tutorial around the newer fragment classes...keep your shorts on. I didn't say I'd never write a TechRepublic tutorial on the topic — I just prefer to eat my Android pie in small bites. Bon appétit!

About

William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

Editor's Picks

Free Newsletters, In your Inbox