1 page.title=Supporting Tablets and Handsets 2 3 @jd:body 4 5 <div id="qv-wrapper"> 6 <ol id="qv"> 7 8 <h2>In this document</h2> 9 <ol> 10 <li><a href="#Guidelines">Basic Guidelines</a></li> 11 <li><a href="#Fragments">Creating Single-pane and Multi-pane Layouts</a></li> 12 <li><a href="#ActionBar">Using the Action Bar</a> 13 <ol> 14 <li><a href="#SplitActionBar">Using split action bar</a></li> 15 <li><a href="#NavigatingUp">Using "up" navigation</a></li> 16 </ol> 17 </li> 18 <li><a href="#Tips">Other Design Tips</a></li> 19 </ol> 20 21 <h2>Related samples</h2> 22 <ol> 23 <li><a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb 24 Gallery</a></li> 25 </ol> 26 27 <h2>See also</h2> 28 <ol> 29 <li><a href="{@docRoot}guide/components/fragments.html">Fragments</a></li> 30 <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li> 31 <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li> 32 </ol> 33 34 35 36 </div> 37 </div> 38 39 40 41 <p>The Android platform runs on a variety of screen sizes and the system gracefully resizes your 42 application's UI to fit each one. Typically, all you need to do is design your UI to be flexible and 43 optimize some elements for different sizes by providing <a 44 href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">alternative 45 resources</a> (such as alternative layouts that reposition some views or alternative 46 dimension values for views). However, sometimes you might want to go a step further to 47 optimize the overall user experience for different screen sizes. For example, tablets offer 48 more space in which your application can present multiple sets of information at once, while a 49 handset device usually requires that you split those sets apart and display them separately. So 50 even though a UI designed for handsets will properly resize to fit a tablet, it does not fully 51 leverage the potential of the tablet's screen to enhance the user experience.</p> 52 53 <p>With Android 3.0 (API level 11), Android introduced a new set of framework APIs that allow you 54 to more effectively design activities that take advantage of large screens: the {@link 55 android.app.Fragment} APIs. Fragments allow you to separate distinct behavioral components of your 56 UI into separate parts, which you can then combine to create multi-pane layouts when running on a 57 tablet or place in separate activities when running on a handset. Android 3.0 also introduced 58 {@link android.app.ActionBar}, which provides a dedicated UI at the top of the screen to identify 59 the app and provide user actions and navigation.</p> 60 61 <p>This document provides guidance that can help you create an application that offers a unique and 62 optimized user experience on both handsets and tablets, using fragments and the action bar.</p> 63 64 <p>Before you continue with this guide, it's important that you first read the 65 guide to <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple 66 Screens</a>. That document describes the fundamental design principles for developing a UI that 67 supports different screen sizes and densities with flexible layouts and alternative bitmaps, 68 respectively.</p> 69 70 71 72 73 <h2 id="Guidelines">Basic Guidelines</h2> 74 75 <p>Here are a few guidelines that will help you create an app that provides an optimized user 76 experience on both tablets and handsets:</p> 77 78 <ul> 79 <li><strong>Build your activity designs based on fragments</strong> that you can reuse in 80 different combinations—in multi-pane layouts on tablets and single-pane layouts on handsets. 81 82 <p>A {@link android.app.Fragment} represents a behavior or a portion of user interface in an 83 activity. You can think of a fragment as a modular section of an activity (a "fragment" of an 84 activity), which has its own lifecycle and which you can add or remove while the activity is 85 running.</p> 86 87 <p>If you haven't used fragments yet, start by reading the <a 88 href="{@docRoot}guide/components/fragments.html">Fragments</a> developer guide.</p> 89 </li> 90 91 92 <li><strong>Use the action bar</strong>, but follow best practices and ensure your design 93 is flexible enough for the system to adjust the action bar layout based on the screen size. 94 95 <p>The {@link android.app.ActionBar} is a UI component for activities that replaces the traditional 96 title bar at the top of the screen. By default, the action bar includes the application logo on the 97 left side, followed by the activity title, and access to items from the options menu on the right 98 side.</p> 99 100 <p>You can enable items from the options menu to appear directly in the action bar as "action 101 items". You can also add navigation features to the action bar, such as tabs or a drop-down list, 102 and use the application icon to supplement the system's <em>Back</em> button behavior with the option to 103 navigate to 104 your application's "home" activity or "up" the application's structural hierarchy.</p> 105 106 <p>This guide provides some tips for using the action bar in ways that support both tablets and 107 handsets. For a detailed discussion of the action bar APIs, read the <a 108 href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guide.</p> 109 </li> 110 111 112 <li><strong>Implement flexible layouts</strong>, as discussed in the 113 <a href="{@docRoot}guide/practices/screens_support.html#screen-independence">Best Practices</a> for 114 supporting multiple screens and the blog post, <a 115 href="http://android-developers.blogspot.com/2011/09/thinking-like-web-designer.html">Thinking 116 Like a Web Designer</a>. 117 <p>A flexible layout design allows your application to adapt to variations in screen 118 sizes. Not all tablets are the same size, nor are all handsets the same size. While you might 119 provide different fragment combinations for "tablets" and "handsets", it's still necessary that 120 each design be flexible to resize to variations in size and aspect ratio.</p> 121 </li> 122 </ul> 123 124 <p>The following sections discuss the first two recommendations in more detail. For more 125 information about creating flexible layouts, refer to the links provided above.</p> 126 127 128 <p class="note"><strong>Note:</strong> Aside from one feature in the action bar, all the 129 APIs needed to accomplish the recommendations in this document are available in Android 130 3.0. Additionally, you can even implement the fragment design patterns and remain 131 backward-compatible with Android 1.6, by using the support library—discussed in the side 132 bar below.</p> 133 134 135 136 <h2 id="Fragments">Creating Single-pane and Multi-pane Layouts</h2> 137 138 139 <div class="sidebox-wrapper"> 140 <div class="sidebox"> 141 <h3>Remaining backward-compatible</h3> 142 <p>If you want to use fragments in your application <em>and</em> remain compatible with 143 versions of Android older than 3.0, you can do so by using the Android <a 144 href="{@docRoot}tools/extras/support-library.html">Support Library</a> (downloadable from the 145 SDK Manager).</p> 146 <p>The support library includes APIs for <a 147 href="{@docRoot}guide/components/fragments.html">fragments</a>, <a 148 href="{@docRoot}guide/components/loaders.html">loaders</a>, and other APIs added in newer 149 versions of Android. By simply adding this library to your Android project, you can use 150 backward-compatible versions of these APIs in your application and remain compatible with Android 151 1.6 (your <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code 152 android:minSdkVersion}</a> value can be as low as {@code "4"}). For information about how to get the 153 library and start using it, see the <a href="{@docRoot}tools/extras/support-library.html">Support 154 Library</a> document.</p> 155 156 <p>The support library <em>does not</em> provide APIs for the action bar, but you can use 157 code from the sample app, <a 158 href="{@docRoot}resources/samples/ActionBarCompat/index.html">Action Bar Compatibility</a>, to 159 create an action bar that supports all devices.</p> 160 </div> 161 </div> 162 163 164 165 166 <p>The most effective way to create a distinct user experience for tablets and handsets is to create 167 layouts with different combinations of fragments, such that you can design "multi-pane" layouts for 168 tablets and "single-pane" layouts for handsets. For example, a news application on a tablet might 169 show a list of articles on the left side and a full article on the right side—selecting an 170 article on the left updates the article view on the right. On a handset, however, these two 171 components should appear on separate screens—selecting an article from a list changes the 172 entire screen to show that article. There are two techniques to accomplish this design with 173 fragments:</p> 174 175 176 <ul> 177 <li><em>Multiple fragments, one activity</em>: Use one activity regardless of the device size, 178 but decide at runtime whether to combine fragments in the layout (to create a multiple-pane design) 179 or swap fragments (to create a single-pane design). Or...</li> 180 181 <li><em>Multiple fragments, multiple activities</em>: On a tablet, place multiple fragments in 182 one activity; on a handset, use separate activities to host each fragment. For example, 183 when the tablet design uses two fragments in an activity, use the same activity for handsets, but 184 supply an alternative layout that includes just the first fragment. When running on a handset and 185 you need to switch fragments (such as when the user selects an item), start another activity that 186 hosts the second fragment.</li> 187 </ul> 188 189 <p>The approach you choose depends on your design and personal preferences. The first option 190 (one activity; swapping fragments) requires that you determine the screen size at runtime 191 and dynamically add each fragment as appropriate—rather than declare the fragments 192 in your activity's XML layout—because you <em>cannot</em> remove a fragment from an activity 193 if it's been declared in the XML layout. When using the first technique, you might also need to 194 update the action bar each time the fragments change, depending on what actions or navigation modes 195 are available for each fragment. In some cases, these factors might not affect your design, so 196 using one activity and swapping fragments might work well (especially if your tablet design requires 197 that you add fragments dynamically anyway). Other times, however, dynamically swapping 198 fragments for your handset design can make your code more complicated, because you must manage all 199 the fragment combinations in the activity's code (rather than use alternative layout resources to 200 define fragment combinations) and manage the back stack of fragments yourself (rather than 201 allow the normal activity stack to handle back-navigation).</p> 202 203 <p>This guide focuses on the second option, in which you display each fragment in a separate 204 activity when on a smaller screen. Using this technique means that you can use alternative layout 205 files that define different fragment combinations for different screen sizes, keep fragment code 206 modular, simplify action bar management, and let the system handle all the back stack work on 207 handsets.</p> 208 209 <p>Figure 1 illustrates how an application with two fragments might be arranged for 210 both handsets and tablets when using separate activities for the handset design:</p> 211 212 <img src="{@docRoot}images/fundamentals/fragments.png" alt="" /> 213 <p class="img-caption"><strong>Figure 1.</strong> Different design patterns for tablets and 214 handsets when selecting an item to view its details.</p> 215 216 <p>In the application shown in figure 1, Activity A is the "main activity" and uses different 217 layouts to display either one or two fragments at a time, depending on the size of the screen:</p> 218 <ul> 219 <li>On a tablet-sized screen, the Activity A layout contains both Fragment A and Fragment B.</li> 220 <li>On a handset-sized screen, the Activity A layout contains only Fragment A (the list 221 view). In order to show the details in Fragment B, Activity B must open.</li> 222 </ul> 223 224 <p class="note"><strong>Note:</strong> Activity B is never used on a tablet. It is simply a 225 container to present Fragment B, so is only used on handset devices when the two fragments must 226 be displayed separately.</p> 227 228 <p>Depending on the screen size, the system applies a different {@code main.xml} layout file:</p> 229 230 <p><code>res/layout/main.xml</code> for handsets:</p> 231 232 <pre> 233 <?xml version="1.0" encoding="utf-8"?> 234 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 235 android:layout_width="match_parent" 236 android:layout_height="match_parent"> 237 <!-- "Fragment A" --> 238 <fragment class="<b>com.example.android.TitlesFragment</b>" 239 android:id="@+id/list_frag" 240 android:layout_width="match_parent" 241 android:layout_height="match_parent"/> 242 </FrameLayout> 243 </pre> 244 245 <p><code>res/layout-large/main.xml</code> for tablets:</p> 246 247 <pre> 248 <?xml version="1.0" encoding="utf-8"?> 249 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 250 android:orientation="horizontal" 251 android:layout_width="match_parent" 252 android:layout_height="match_parent" 253 android:id="@+id/frags"> 254 <!-- "Fragment A" --> 255 <fragment class="<b>com.example.android.TitlesFragment</b>" 256 android:id="@+id/list_frag" 257 android:layout_width="@dimen/titles_size" 258 android:layout_height="match_parent"/> 259 <!-- "Fragment B" --> 260 <fragment class="<b>com.example.android.DetailsFragment</b>" 261 android:id="@+id/details_frag" 262 android:layout_width="match_parent" 263 android:layout_height="match_parent" /> 264 </LinearLayout> 265 </pre> 266 267 268 <div class="sidebox-wrapper"> 269 <div class="sidebox"> 270 <h3>Supporting sizes based on screen width</h3> 271 <p>Android 3.2 (API level 13) adds new APIs that provide more fine-grain control over what screen 272 sizes your app supports and what resources it uses, by declaring screen sizes based on the minimum 273 width your layouts require. For example, both a 5" and 7" device qualify as a "large" screen, so 274 your "large" layout resources are used on both devices. With API level 13, you can distinguish 275 between these two sizes based on the screen width, as measured in density-independent pixels.</p> 276 <p>For details, read the blog post about <a 277 href="http://android-developers.blogspot.com/2011/07/new-tools-for-managing-screen-sizes.html"> 278 New Tools for Managing Screen Sizes</a>.</p> 279 </div> 280 </div> 281 282 <p class="note"><strong>Note:</strong> Although the above sample layout for tablets is based on 283 the "large" screen configuration qualifier, you should also use the new "minimum width" size 284 qualifiers in order to more precisely control the screen size at which the system applies your 285 handset or tablet layout. See the sidebar for more information.</p> 286 287 <p>How the application responds when a user selects an item from the list depends on whether 288 Fragment B is available in the layout:</p> 289 <ul> 290 <li>If Fragment B is in the layout, Activity A notifies Fragment B to update itself.</li> 291 <li>If Fragment B is <em>not</em> in the layout, Activity A starts Activity B (which hosts 292 Fragment B).</li> 293 </ul> 294 295 296 <p>To implement this pattern for your application, it's important 297 that you develop your fragments to be highly compartmentalized. Specifically, you should follow two 298 guidelines:</p> 299 300 <ul> 301 <li>Do not manipulate one fragment directly from another.</li> 302 <li>Keep all code that concerns content in a fragment inside that fragment, rather than putting it 303 in the host activity's code.</li> 304 </ul> 305 306 <p>To avoid directly calling one fragment from another, <strong>define a callback interface in each 307 fragment</strong> class that it can use to deliver events to 308 its host activity, which implements the callback 309 interface. When the activity receives a callback due to an event (such as the user selecting a list 310 item), the activity responds appropriately based on the current fragment configuration.</p> 311 312 <p>For example, Activity A from above can handle item selections depending on whether it's using 313 the tablet or handset layout like this:</p> 314 315 <pre> 316 public class MainActivity extends Activity implements TitlesFragment.OnItemSelectedListener { 317 ... 318 319 /** This is a callback that the list fragment (Fragment A) 320 calls when a list item is selected */ 321 public void onItemSelected(int position) { 322 DisplayFragment displayFrag = (DisplayFragment) getFragmentManager() 323 .findFragmentById(R.id.display_frag); 324 if (displayFrag == null) { 325 // DisplayFragment (Fragment B) is not in the layout (handset layout), 326 // so start DisplayActivity (Activity B) 327 // and pass it the info about the selected item 328 Intent intent = new Intent(this, DisplayActivity.class); 329 intent.putExtra("position", position); 330 startActivity(intent); 331 } else { 332 // DisplayFragment (Fragment B) is in the layout (tablet layout), 333 // so tell the fragment to update 334 displayFrag.updateContent(position); 335 } 336 } 337 } 338 </pre> 339 340 <p>When <code>DisplayActivity</code> (Activity B) starts, it reads the data delivered by the 341 {@link android.content.Intent} and passes it to the <code>DisplayFragment</code> (Fragment B).</p> 342 343 <p>If Fragment B needs to deliver a result back to Fragment A (because Activity B was started with 344 {@link android.app.Activity#startActivityForResult startActivityForResult()}), then the process 345 works similarly with a callback interface between Fragment B and Activity B. That is, Activity B 346 implements a different callback interface defined by Fragment B. When Activity B receives the 347 callback with a result from the fragment, it sets the result for the activity (with {@link 348 android.app.Activity#setResult setResult()}) and finishes itself. Activity A then receives the 349 result and delivers it to Fragment A.</p> 350 351 <p>For a demonstration of this technique for creating different fragment combinations for 352 tablets and handsets, see the updated version of the <a 353 href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> 354 sample.</p> 355 356 357 358 359 360 361 <h2 id="ActionBar">Using the Action Bar</h2> 362 363 <p>The <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> is an important UI 364 component for Android apps on both tablets and handsets. To ensure that the action bar 365 behaves appropriately on all screen sizes, it's important that you use the {@link 366 android.app.ActionBar} APIs without adding complex customizations. By using the standard {@link 367 android.app.ActionBar} APIs to design your action bar, the Android system does all 368 the work to gracefully adapt the action bar for different screen sizes. Here are some important 369 tips to follow when creating your action bar:</p> 370 371 <ul> 372 <li>When setting a menu item to be an action item, <strong>avoid using the {@code "always"} 373 value</strong>. In your <a 374 href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>, use {@code "ifRoom"} 375 for the {@code android:showAsAction} attribute if you'd like the menu item to appear in the action 376 bar. However, you might need {@code "always"} when an action view does not provide a default 377 action for the overflow menu (that is, it must appear as an action view). However, 378 you should not use {@code "always"} more than once or twice. In almost all other cases, use {@code 379 "ifRoom"} as the value for {@code "android:showAsAction"} when you want the item to appear as an 380 action item. Forcing too many action items into the action bar can create a cluttered UI and 381 action items may overlap with other action bar elements such as the title or navigation items.</li> 382 383 <li>When adding action items to the action bar with a text title, also <strong>provide an 384 icon</strong>, when appropriate, and declare <code>showAsAction="ifRoom|withText"</code>. 385 This way, if there's not enough room for the title, but there is enough room for the icon, then only 386 the icon may be used.</li> 387 388 389 <li>Always <strong>provide a title</strong> for your action items, even if you don't enable {@code 390 "withText"}, because users can view the title as a "tool-tip" by performing a 391 "long click" on the item—the title text appears momentarily in a toast message. Providing 392 a title is also critical for accessibility, because screen readers read aloud the item title 393 even when not visible.</li> 394 395 396 <li><strong>Avoid using custom navigation modes when possible</strong>. Use the built-in tab 397 and drop-down navigation modes when possible—they're designed so the system can adapt their 398 presentation to different screen sizes. For example, when the width is too narrow for both tabs and 399 other action items (such as a handset in portrait orientation), the tabs appear below the action bar 400 (this is known as the "stacked action bar"). If you must build a custom navigation mode or other 401 custom views in the action bar, thoroughly test them on smaller screens and make any 402 necessary adjustments to support a narrow action bar.</li> 403 </ul> 404 405 <p>For example, the mock-ups below demonstrate how the system may adapt an action bar based 406 on the available screen space. On the handset, only two action items fit, so the remaining menu 407 items appear in the overflow menu (because {@code android:showAsAction} was set to {@code "ifRoom"}) 408 and the tabs appear in a separate row (the stacked action bar). On the tablet, more action items can 409 fit in the action bar and so do the tabs.</p> 410 411 <img src="{@docRoot}images/practices/actionbar-phone-tablet.png" alt=""/> 412 <p class="img-caption"><strong>Figure 2.</strong> Mock-up showing how the system re-configures 413 action bar components based on the available screen space.</p> 414 415 416 <h3 id="SplitActionBar">Using split action bar</h3> 417 418 <p>When your application is running on Android 4.0 (API level 14) and 419 higher, there's an extra mode available for the action bar called "split action bar." When 420 you enable split action bar, a separate bar appears at the bottom of the screen to 421 display all action items when the activity is running on a narrow screen (such as a portrait 422 handset). Splitting the action bar ensures that a reasonable amount of space is available to 423 display action items on a narrow screen and also leave room for navigation and title elements 424 at the top.</p> 425 426 <p>To enable split action bar, simply add {@code uiOptions="splitActionBarWhenNarrow"} to your 427 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> or 428 <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> 429 manifest element.</p> 430 431 432 <img src="{@docRoot}images/practices/actionbar-phone-splitaction.png" alt=""/> 433 <p class="img-caption"><strong>Figure 3.</strong> Split action bar with navigation tabs on the left; 434 with the app icon and title disabled on the right.</p> 435 436 437 <p>If you'd like to hide the main action bar at the top, because you're using the built-in 438 navigation tabs along with the split action bar, call {@link 439 android.app.ActionBar#setDisplayShowHomeEnabled setDisplayShowHomeEnabled(false)} to disable the 440 application icon in the action bar. In this case, there's now nothing left in the main action bar, 441 so it disappears and all thats left are the navigation tabs at the top and the action items at the 442 bottom, as shown by the second device in figure 3.</p> 443 444 <p class="note"><strong>Note:</strong> Although the {@code uiOptions} attribute was added in Android 445 4.0 (API level 14), you can safely include it in your application even if your <a 446 href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> is set to 447 a value lower than {@code "14"} to remain compatible with older versions of Android. When running on 448 older versions, the system simply ignores the attribute because it doesn't understand it. The only 449 condition to adding it to your manifest is that you must compile your application against a platform 450 version that supports API level 14 or higher. Just be sure that you don't openly use other APIs in 451 your application code that aren't supported by the version declared by your <a 452 href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> 453 attribute.</p> 454 455 456 <h3 id="NavigatingUp">Using "up" navigation</h3> 457 458 <p>As discussed in the <a href="{@docRoot}guide/topics/ui/actionbar.html#Home">Action Bar</a> 459 developer guide, you can use the application icon in the action bar to facilitate user navigation 460 when appropriate—either as a method to get back to the "home" activity (similar to clicking 461 the logo on a web site) or as a way to navigate up the application's structural hierarchy. Although 462 it might seem similar to the standard <em>Back</em> navigation in some cases, the up navigation 463 option 464 provides a more predictable navigation method for situations in which the user may have entered 465 from an external location, such as a notification, app widget, or a different application.</p> 466 467 <p>When using fragments in different combinations for different devices, it's important to give 468 extra consideration to how your up navigation behaves in each configuration. For example, when on a 469 handset and your application shows just one fragment at a time, it might be appropriate to enable up 470 navigation to go up to the parent screen, whereas it's not necessary when showing the same 471 fragment in a multi-pane configuration.</p> 472 473 <p>For more information about enabling up navigation, see the <a 474 href="{@docRoot}guide/topics/ui/actionbar.html#Home">Action Bar</a> developer guide.</p> 475 476 477 478 479 <h2 id="Tips">Other Design Tips</h2> 480 481 <ul> 482 <li>When working with a {@link android.widget.ListView}, consider how you might provide more or less 483 information in each list item based on the available space. That is, you can create alternative 484 layouts to be used by the items in your list adapter such that a large screen might display more 485 detail for each item.</li> 486 <li>Create <a href="{@docRoot}guide/topics/resources/more-resources.html">alternative resource 487 files</a> for values such as integers, dimensions, and even booleans. Using size qualifiers for 488 these resources, you can easily apply different layout sizes, font sizes, or enable/disable features 489 based on the current screen size.</li> 490 </ul> 491 492 493