• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Tabbed
2parent.title=Layouts
3parent.link=layout-objects.html
4@jd:body
5<div id="qv-wrapper">
6<div id="qv">
7<h2>In this document</h2>
8  <ol>
9    <li><a href="#example">Example</a></li>
10  </ol>
11  <h2>Key classes</h2>
12  <ol>
13<li>{@link android.widget.TabWidget}</li>
14<li>{@link android.widget.TabHost}</li>
15<li>{@link android.widget.TabHost.TabSpec}</li>
16<li>{@link android.widget.FrameLayout}</li>
17  </ol>
18</div>
19</div>
20<p>To create a tabbed UI, you need to use a {@link android.widget.TabHost} and a {@link
21android.widget.TabWidget}. The {@link android.widget.TabHost} must be the root node for the layout,
22which contains both the {@link android.widget.TabWidget} for displaying the tabs and a {@link
23android.widget.FrameLayout} for displaying the tab content.</p>
24
25<img src="{@docRoot}images/ui/tabs.png" alt="" />
26
27<p>You can implement your tab content in one of two ways: use the tabs to swap
28{@link android.view.View}s within the same {@link android.app.Activity}, or use the tabs to change
29between entirely separate activities. Which method you want for your application will depend on your
30demands, but if each tab provides a distinct user activity, then it probably makes sense to use
31a separate {@link android.app.Activity} for each tab, so that you can better manage the application
32in discrete groups, rather than one massive application and layout.</p>
33<h2 id="example">Example</h2>
34<p>In this tutorial, you'll create a tabbed UI that uses a separate {@link
35android.app.Activity} for each tab.</p>
36
37<ol>
38  <li>Start a new project named <em>HelloTabWidget</em>.</li>
39  <li>First, create three separate {@link android.app.Activity} classes in your project:
40<code>ArtistsActivity</code>, <code>AlbumsActivity</code>, and <code>SongsActivity</code>. These
41will each represent a separate tab. For now, make each one display a simple message using a {@link
42android.widget.TextView}. For example:
43<pre>
44public class ArtistsActivity extends Activity {
45    public void onCreate(Bundle savedInstanceState) {
46        super.onCreate(savedInstanceState);
47
48        TextView textview = new TextView(this);
49        textview.setText("This is the Artists tab");
50        setContentView(textview);
51    }
52}
53</pre>
54  <p>Notice that this doesn't use a layout file. Just create a {@link
55android.widget.TextView}, give it some text and set that as the content. Duplicate this for
56each of the three activities, and add the corresponding <code>&lt;activity/&gt;</code> tags to the Android Manifest file.</p>
57
58  <li>You need an icon for each of your tabs. For each icon, you should create two versions: one
59for when the tab is selected and one for when it is unselected. The
60general design recommendation is for the selected icon to be a dark color (grey), and the
61unselected icon to be a light color (white). (See the <a
62href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#tabstructure">Icon Design
63Guidelines</a>.) For example:
64  <p>
65  <img src="images/ic_tab_artists_white.png" title="unselected tab icon"  alt="" />
66  <img src="images/ic_tab_artists_grey.png" title="selected tab icon" alt="" />
67  </p>
68  <p>For this tutorial, you can copy these images and use them for all three tabs. (When you
69create tabs in your own application, you should create customized tab icons.)</p>
70  <p>Now create a <a
71href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state-list drawable</a>
72that specifies which image to use for each tab state:</p>
73  <ol>
74    <li>Save the icon images in your project <code>res/drawable/</code> directory.</li>
75    <li>Create a new XML file in <code>res/drawable/</code>
76named <code>ic_tab_artists.xml</code> and insert the following:
77<pre>
78&lt;?xml version="1.0" encoding="utf-8"?>
79&lt;selector xmlns:android="http://schemas.android.com/apk/res/android">
80    &lt;!-- When selected, use grey -->
81    &lt;item android:drawable="@drawable/ic_tab_artists_grey"
82          android:state_selected="true" />
83    &lt;!-- When not selected, use white-->
84    &lt;item android:drawable="@drawable/ic_tab_artists_white" />
85&lt;/selector>
86</pre>
87  <p>This is a <a
88href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state-list drawable</a>,
89which you will apply as the tab image. When the tab state changes, the tab icon will
90automatically switch between the images defined here.</p>
91    </li>
92  </ol>
93  </li>
94
95  <li>Open the <code>res/layout/main.xml</code> file and insert the following:
96  <pre>
97&lt;?xml version="1.0" encoding="utf-8"?>
98&lt;TabHost xmlns:android="http://schemas.android.com/apk/res/android"
99    android:id="@android:id/tabhost"
100    android:layout_width="fill_parent"
101    android:layout_height="fill_parent">
102    &lt;LinearLayout
103        android:orientation="vertical"
104        android:layout_width="fill_parent"
105        android:layout_height="fill_parent"
106        android:padding="5dp">
107        &lt;TabWidget
108            android:id="@android:id/tabs"
109            android:layout_width="fill_parent"
110            android:layout_height="wrap_content" />
111        &lt;FrameLayout
112            android:id="@android:id/tabcontent"
113            android:layout_width="fill_parent"
114            android:layout_height="fill_parent"
115            android:padding="5dp" />
116    &lt;/LinearLayout>
117&lt;/TabHost>
118</pre>
119    <p>This is the layout that will display the tabs and provide navigation between each {@link
120    android.app.Activity} created above.</p>
121    <p>The {@link android.widget.TabHost} requires that a {@link android.widget.TabWidget} and a
122{@link android.widget.FrameLayout} both live somewhere within it. To position the {@link
123android.widget.TabWidget} and {@link android.widget.FrameLayout} vertically, a {@link
124android.widget.LinearLayout} is used. The {@link android.widget.FrameLayout} is where the content
125for each tab goes, which is empty now because the {@link android.widget.TabHost} will automatically
126embed each {@link android.app.Activity} within it.</p>
127    <p>Notice that the {@link android.widget.TabWidget} and the {@link android.widget.FrameLayout}
128    elements have the IDs {@code tabs} and {@code tabcontent}, respectively. These names
129    must be used so that the {@link android.widget.TabHost} can retrieve references to each of
130    them. It expects exactly these names.</p>
131  </li>
132
133  <li>Now open <code>HelloTabWidget.java</code> and make it extend {@link
134  android.app.TabActivity}:</p>
135<pre>
136public class HelloTabWidget extends TabActivity {
137</pre>
138  </li>
139  <li>Use the following code for the {@link android.app.Activity#onCreate(Bundle) onCreate()}
140  method:
141<pre>
142public void onCreate(Bundle savedInstanceState) {
143    super.onCreate(savedInstanceState);
144    setContentView(R.layout.main);
145
146    Resources res = getResources(); // Resource object to get Drawables
147    TabHost tabHost = getTabHost();  // The activity TabHost
148    TabHost.TabSpec spec;  // Resusable TabSpec for each tab
149    Intent intent;  // Reusable Intent for each tab
150
151    // Create an Intent to launch an Activity for the tab (to be reused)
152    intent = new Intent().setClass(this, ArtistsActivity.class);
153
154    // Initialize a TabSpec for each tab and add it to the TabHost
155    spec = tabHost.newTabSpec("artists").setIndicator("Artists",
156                      res.getDrawable(R.drawable.ic_tab_artists))
157                  .setContent(intent);
158    tabHost.addTab(spec);
159
160    // Do the same for the other tabs
161    intent = new Intent().setClass(this, AlbumsActivity.class);
162    spec = tabHost.newTabSpec("albums").setIndicator("Albums",
163                      res.getDrawable(R.drawable.ic_tab_albums))
164                  .setContent(intent);
165    tabHost.addTab(spec);
166
167    intent = new Intent().setClass(this, SongsActivity.class);
168    spec = tabHost.newTabSpec("songs").setIndicator("Songs",
169                      res.getDrawable(R.drawable.ic_tab_songs))
170                  .setContent(intent);
171    tabHost.addTab(spec);
172
173    tabHost.setCurrentTab(2);
174}
175</pre>
176    <p>This sets up each tab with their text and icon, and assigns each one an {@link
177android.app.Activity}.</p>
178    <p>A reference to the {@link android.widget.TabHost} is first captured with {@link
179android.app.TabActivity#getTabHost()}. Then, for
180each tab, a {@link android.widget.TabHost.TabSpec} is created to define the tab properties. The
181{@link android.widget.TabHost#newTabSpec(String)} method creates a new {@link
182android.widget.TabHost.TabSpec} identified by the given string tag. For each
183{@link android.widget.TabHost.TabSpec}, {@link
184android.widget.TabHost.TabSpec#setIndicator(CharSequence,Drawable)} is called to set the text and
185icon for the tab, and {@link android.widget.TabHost.TabSpec#setContent(Intent)} is called to specify
186the {@link android.content.Intent} to open the appropriate {@link android.app.Activity}. Each
187{@link android.widget.TabHost.TabSpec} is then added to the {@link android.widget.TabHost} by
188calling {@link android.widget.TabHost#addTab(TabHost.TabSpec)}.</p>
189
190    <p>At the very end, {@link
191    android.widget.TabHost#setCurrentTab(int)} opens the tab to be displayed by default, specified
192    by the index position of the tab.</p>
193
194    <p>Notice that not once was the {@link android.widget.TabWidget} object referenced. This is
195    because a {@link android.widget.TabWidget} must always be a child of a {@link
196    android.widget.TabHost}, which is what you use for almost all interaction with the tabs. So when
197    a tab is added to the {@link android.widget.TabHost}, it's automatically added to the child
198    {@link android.widget.TabWidget}.</p>
199  </li>
200
201  <li>Now open the Android Manifest file and add the <code>NoTitleBar</code> theme to the
202<em>HelloTabWidget</em>'s
203  <code>&lt;activity></code> tag. This will remove the default application title from the top
204  of the layout, leaving more space for the tabs, which effectively operate as their own titles.
205  The <code>&lt;activity></code> tag should look like this:
206<pre>
207&lt;activity android:name=".HelloTabWidget" android:label="@string/app_name"
208          android:theme="&#64;android:style/Theme.NoTitleBar">
209</pre>
210  </li>
211
212  <li>Run the application.</li>
213</ol>
214
215
216<p>Your application should look like this (though your icons may be different):</p>
217<img src="images/hello-tabwidget.png" width="150px" />
218
219
220