1 page.title=Tabbed 2 parent.title=Layouts 3 parent.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 21 android.widget.TabWidget}. The {@link android.widget.TabHost} must be the root node for the layout, 22 which contains both the {@link android.widget.TabWidget} for displaying the tabs and a {@link 23 android.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 29 between entirely separate activities. Which method you want for your application will depend on your 30 demands, but if each tab provides a distinct user activity, then it probably makes sense to use 31 a separate {@link android.app.Activity} for each tab, so that you can better manage the application 32 in 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 35 android.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 41 will each represent a separate tab. For now, make each one display a simple message using a {@link 42 android.widget.TextView}. For example: 43 <pre> 44 public 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 55 android.widget.TextView}, give it some text and set that as the content. Duplicate this for 56 each of the three activities, and add the corresponding <code><activity/></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 59 for when the tab is selected and one for when it is unselected. The 60 general design recommendation is for the selected icon to be a dark color (grey), and the 61 unselected icon to be a light color (white). (See the <a 62 href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#tabstructure">Icon Design 63 Guidelines</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 69 create tabs in your own application, you should create customized tab icons.)</p> 70 <p>Now create a <a 71 href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state-list drawable</a> 72 that 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> 76 named <code>ic_tab_artists.xml</code> and insert the following: 77 <pre> 78 <?xml version="1.0" encoding="utf-8"?> 79 <selector xmlns:android="http://schemas.android.com/apk/res/android"> 80 <!-- When selected, use grey --> 81 <item android:drawable="@drawable/ic_tab_artists_grey" 82 android:state_selected="true" /> 83 <!-- When not selected, use white--> 84 <item android:drawable="@drawable/ic_tab_artists_white" /> 85 </selector> 86 </pre> 87 <p>This is a <a 88 href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state-list drawable</a>, 89 which you will apply as the tab image. When the tab state changes, the tab icon will 90 automatically 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 <?xml version="1.0" encoding="utf-8"?> 98 <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 <LinearLayout 103 android:orientation="vertical" 104 android:layout_width="fill_parent" 105 android:layout_height="fill_parent" 106 android:padding="5dp"> 107 <TabWidget 108 android:id="@android:id/tabs" 109 android:layout_width="fill_parent" 110 android:layout_height="wrap_content" /> 111 <FrameLayout 112 android:id="@android:id/tabcontent" 113 android:layout_width="fill_parent" 114 android:layout_height="fill_parent" 115 android:padding="5dp" /> 116 </LinearLayout> 117 </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 123 android.widget.TabWidget} and {@link android.widget.FrameLayout} vertically, a {@link 124 android.widget.LinearLayout} is used. The {@link android.widget.FrameLayout} is where the content 125 for each tab goes, which is empty now because the {@link android.widget.TabHost} will automatically 126 embed 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> 136 public 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> 142 public 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 177 android.app.Activity}.</p> 178 <p>A reference to the {@link android.widget.TabHost} is first captured with {@link 179 android.app.TabActivity#getTabHost()}. Then, for 180 each 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 182 android.widget.TabHost.TabSpec} identified by the given string tag. For each 183 {@link android.widget.TabHost.TabSpec}, {@link 184 android.widget.TabHost.TabSpec#setIndicator(CharSequence,Drawable)} is called to set the text and 185 icon for the tab, and {@link android.widget.TabHost.TabSpec#setContent(Intent)} is called to specify 186 the {@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 188 calling {@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><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><activity></code> tag should look like this: 206 <pre> 207 <activity android:name=".HelloTabWidget" android:label="@string/app_name" 208 android:theme="@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