Home | History | Annotate | Download | only in backward-compatible-ui
      1 page.title=Using the Version-Aware Component
      2 parent.title=Creating Backward-Compatible UIs
      3 parent.link=index.html
      4 
      5 trainingnavtop=true
      6 previous.title=Creating an Implementation with Older APIs
      7 previous.link=older-implementation.html
      8 
      9 @jd:body
     10 
     11 <div id="tb-wrapper">
     12 <div id="tb">
     13 
     14 <h2>This lesson teaches you to:</h2>
     15 <ol>
     16   <li><a href="#switching-logic">Add the Switching Logic</a></li>
     17   <li><a href="#layout">Create a Version-Aware Activity Layout</a></li>
     18   <li><a href="#use-tabhelper">Use TabHelper in Your Activity</a></li>
     19 </ol>
     20 
     21 <h2>Try it out</h2>
     22 
     23 <div class="download-box">
     24 <a href="http://developer.android.com/shareables/training/TabCompat.zip"
     25   class="button">Download the sample app</a>
     26 <p class="filename">TabCompat.zip</p>
     27 </div>
     28 
     29 </div>
     30 </div>
     31 
     32 <p>Now that you have two implementations of <code>TabHelper</code> and <code>CompatTab</code>&mdash;one for Android 3.0 and later and one for earlier versions of the platform&mdash;it's time to do something with these implementations. This lesson discusses creating the logic for switching between these implementations, creating version-aware layouts, and finally using the backward-compatible UI component.</p>
     33 
     34 <h2 id="switching-logic">Add the Switching Logic</h2>
     35 
     36 <p>The <code>TabHelper</code> abstract class acts as a <a href="http://en.wikipedia.org/wiki/Factory_(software_concept)">factory</a> for creating version-appropriate <code>TabHelper</code> and <code>CompatTab</code> instances, based on the current device's platform version:</p>
     37 
     38 <pre>
     39 public abstract class TabHelper {
     40     ...
     41     // Usage is TabHelper.createInstance(activity)
     42     public static TabHelper createInstance(FragmentActivity activity) {
     43         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
     44             return new TabHelperHoneycomb(activity);
     45         } else {
     46             return new TabHelperEclair(activity);
     47         }
     48     }
     49 
     50     // Usage is mTabHelper.newTab("tag")
     51     public CompatTab newTab(String tag) {
     52         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
     53             return new CompatTabHoneycomb(mActivity, tag);
     54         } else {
     55             return new CompatTabEclair(mActivity, tag);
     56         }
     57     }
     58     ...
     59 }
     60 </pre>
     61 
     62 <h2 id="layout">Create a Version-Aware Activity Layout</h2>
     63 
     64 <p>The next step is to provide layouts for your activity that can support the two tab implementations. For the older implementation (<code>TabHelperEclair</code>), you need to ensure that your activity layout contains a {@link android.widget.TabWidget} and {@link android.widget.TabHost}, along with a container for tab contents:</p>
     65 
     66 <p><strong>res/layout/main.xml:</strong></p>
     67 
     68 <pre>
     69 &lt;!-- This layout is for API level 5-10 only. --&gt;
     70 &lt;TabHost xmlns:android="http://schemas.android.com/apk/res/android"
     71     android:id="@android:id/tabhost"
     72     android:layout_width="match_parent"
     73     android:layout_height="match_parent"&gt;
     74 
     75     &lt;LinearLayout
     76         android:orientation="vertical"
     77         android:layout_width="match_parent"
     78         android:layout_height="match_parent"
     79         android:padding="5dp"&gt;
     80 
     81         &lt;TabWidget
     82             android:id="@android:id/tabs"
     83             android:layout_width="match_parent"
     84             android:layout_height="wrap_content" /&gt;
     85 
     86         &lt;FrameLayout
     87             android:id="@android:id/tabcontent"
     88             android:layout_width="match_parent"
     89             android:layout_height="0dp"
     90             android:layout_weight="1" /&gt;
     91 
     92     &lt;/LinearLayout&gt;
     93 &lt;/TabHost&gt;
     94 </pre>
     95 
     96 <p>For the <code>TabHelperHoneycomb</code> implementation, all you need is a {@link android.widget.FrameLayout} to contain the tab contents, since the tab indicators are provided by the {@link android.app.ActionBar}:</p>
     97 
     98 <p><strong>res/layout-v11/main.xml:</strong></p>
     99 
    100 <pre>
    101 &lt;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    102     android:id="@android:id/tabcontent"
    103     android:layout_width="match_parent"
    104     android:layout_height="match_parent" /&gt;
    105 </pre>
    106 
    107 <p>At runtime, Android will decide which version of the <code>main.xml</code> layout to inflate depending on the platform version. This is the same logic shown in the previous section to determine which <code>TabHelper</code> implementation to use.</p>
    108 
    109 <h2 id="use-tabhelper">Use TabHelper in Your Activity</h2>
    110 
    111 <p>In your activity's {@link android.app.Activity#onCreate onCreate()} method, you can obtain a <code>TabHelper</code> object and add tabs with the following code:</p>
    112 
    113 <pre>
    114 {@literal @}Override
    115 public void onCreate(Bundle savedInstanceState) {
    116     setContentView(R.layout.main);
    117 
    118     TabHelper tabHelper = TabHelper.createInstance(this);
    119     tabHelper.setUp();
    120 
    121     CompatTab photosTab = tabHelper
    122             .newTab("photos")
    123             .setText(R.string.tab_photos);
    124     tabHelper.addTab(photosTab);
    125 
    126     CompatTab videosTab = tabHelper
    127             .newTab("videos")
    128             .setText(R.string.tab_videos);
    129     tabHelper.addTab(videosTab);
    130 }
    131 </pre>
    132 
    133 <p>When running the application, this code inflates the correct activity layout and instantiates either a <code>TabHelperHoneycomb</code> or <code>TabHelperEclair</code> object. The concrete class that's actually used is opaque to the activity, since they share the common <code>TabHelper</code> interface.</p>
    134 
    135 <p>Below are two screenshots of this implementation running on an Android 2.3 and Android 4.0 device.</p>
    136 
    137 <img src="{@docRoot}images/training/backward-compatible-ui-gb.png"
    138   alt="Example screenshot of tabs running on an Android 2.3 device (using TabHelperEclair)." width="200">
    139 
    140 <img src="{@docRoot}images/training/backward-compatible-ui-ics.png"
    141   alt="Example screenshots of tabs running on an Android 4.0 device (using TabHelperHoneycomb)." width="200">
    142 
    143 <p class="img-caption"><strong>Figure 1.</strong> Example screenshots of backward-compatible tabs running on an Android 2.3 device (using <code>TabHelperEclair</code>) and an Android 4.0 device (using <code>TabHelperHoneycomb</code>).</p>
    144