Home | History | Annotate | Download | only in playback
      1 page.title=Creating a Catalog Browser
      2 page.tags=tv, browsefragment, presenter, backgroundmanager
      3 helpoutsWidget=true
      4 
      5 trainingnavtop=true
      6 
      7 @jd:body
      8 
      9 <div id="tb-wrapper">
     10 <div id="tb">
     11   <h2>This lesson teaches you to</h2>
     12   <ol>
     13     <li><a href="#layout">Create a Media Browse Layout</a></li>
     14     <li><a href="#lists">Display Media Lists</a></li>
     15     <li><a href="#background">Update the Background</a></li>
     16   </ol>
     17 
     18 </div>
     19 </div>
     20 
     21 <p>
     22   Media apps that run on TV need to allow users to browse its content offerings, make a
     23   selection, and start playing content. The content browsing experience for apps of this type
     24   should be simple and intuitive, as well as visually pleasing and engaging.
     25 </p>
     26 
     27 <p>
     28   This lesson discusses how to use the classes provided by the <a href=
     29   "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support library</a> to
     30   implement a user interface for browsing music or videos from your app's media catalog.
     31 </p>
     32 
     33 
     34 <h2 id="layout">Create a Media Browse Layout</h2>
     35 
     36 <p>
     37   The {@link android.support.v17.leanback.app.BrowseFragment} class in the leanback library
     38   allows you to create a primary layout for browsing categories and rows of media items with a
     39   minimum of code. The following example shows how to create a layout that contains a {@link
     40   android.support.v17.leanback.app.BrowseFragment}:
     41 </p>
     42 
     43 <pre>
     44 &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     45   android:layout_width=&quot;match_parent&quot;
     46   android:layout_height=&quot;match_parent&quot;
     47   android:orientation=&quot;vertical&quot;
     48   &gt;
     49 
     50   &lt;fragment
     51       <strong>android:name="android.support.v17.leanback.app.BrowseFragment"</strong>
     52       android:id=&quot;@+id/browse_fragment&quot;
     53       android:layout_width=&quot;match_parent&quot;
     54       android:layout_height=&quot;match_parent&quot;
     55       /&gt;
     56 &lt;/LinearLayout&gt;
     57 </pre>
     58 
     59 <p>
     60   In order to work with this layout in an activity, retrieve the {@link
     61   android.support.v17.leanback.app.BrowseFragment} element from the layout. Use the methods in this
     62   class to set display parameters such as the icon, title, and whether category headers are enabled.
     63   The following code sample demonstrates how to set the layout parameters for a {@link
     64   android.support.v17.leanback.app.BrowseFragment} in a layout:
     65 </p>
     66 
     67 <pre>
     68 public class BrowseMediaActivity extends Activity {
     69 
     70     public static final String TAG ="BrowseActivity";
     71 
     72     protected BrowseFragment mBrowseFragment;
     73 
     74     &#64;Override
     75     protected void onCreate(Bundle savedInstanceState) {
     76         super.onCreate(savedInstanceState);
     77         setContentView(R.layout.browse_fragment);
     78 
     79         final FragmentManager fragmentManager = getFragmentManager();
     80         <strong>mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById(
     81                 R.id.browse_fragment);</strong>
     82 
     83         // Set display parameters for the BrowseFragment
     84         mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED);
     85         mBrowseFragment.setTitle(getString(R.string.app_name));
     86         mBrowseFragment.setBadgeDrawable(getResources().getDrawable(
     87                 R.drawable.ic_launcher));
     88         mBrowseFragment.setBrowseParams(params);
     89 
     90     }
     91 }
     92 </pre>
     93 
     94 
     95 <h2 id="lists">Displaying Media Lists</h2>
     96 
     97 <p>
     98   The {@link android.support.v17.leanback.app.BrowseFragment} allows you to define and display
     99   browsable media content categories and media items from a media catalog using adapters and
    100   presenters. Adapters enable you to connect to local or online data sources that contain your
    101   media catalog information. Presenters hold data about media items and provide layout information
    102   for displaying an item on screen.
    103 </p>
    104 
    105 <p>
    106   The following example code shows an implementation of a {@link
    107   android.support.v17.leanback.widget.Presenter} for displaying string data:
    108 </p>
    109 
    110 <pre>
    111 public class StringPresenter extends Presenter {
    112     private static final String TAG = "StringPresenter";
    113 
    114     public ViewHolder onCreateViewHolder(ViewGroup parent) {
    115         TextView textView = new TextView(parent.getContext());
    116         textView.setFocusable(true);
    117         textView.setFocusableInTouchMode(true);
    118         textView.setBackground(
    119                 parent.getContext().getResources().getDrawable(R.drawable.text_bg));
    120         return new ViewHolder(textView);
    121     }
    122 
    123     public void onBindViewHolder(ViewHolder viewHolder, Object item) {
    124         ((TextView) viewHolder.view).setText(item.toString());
    125     }
    126 
    127     public void onUnbindViewHolder(ViewHolder viewHolder) {
    128         // no op
    129     }
    130 }
    131 </pre>
    132 
    133 <p>
    134   Once you have constructed a presenter class for your media items, you can build and attach an
    135   adapter to the {@link android.support.v17.leanback.app.BrowseFragment} to display those items on
    136   screen for browsing by the user. The following example code demonstrates how to construct an
    137   adapter to display categories and items in those categories using the {@code StringPresenter}
    138   class shown in the previous code example:
    139 </p>
    140 
    141 <pre>
    142 private ArrayObjectAdapter mRowsAdapter;
    143 private static final int NUM_ROWS = 4;
    144 
    145 &#64;Override
    146 protected void onCreate(Bundle savedInstanceState) {
    147     ...
    148 
    149     buildRowsAdapter();
    150 }
    151 
    152 private void buildRowsAdapter() {
    153     mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
    154 
    155     for (int i = 0; i &lt; NUM_ROWS; ++i) {
    156         ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
    157                 new StringPresenter());
    158         listRowAdapter.add("Media Item 1");
    159         listRowAdapter.add("Media Item 2");
    160         listRowAdapter.add("Media Item 3");
    161         HeaderItem header = new HeaderItem(i, "Category " + i, null);
    162         mRowsAdapter.add(new ListRow(header, listRowAdapter));
    163     }
    164 
    165     mBrowseFragment.setAdapter(mRowsAdapter);
    166 }
    167 </pre>
    168 
    169 <p>
    170   This example shows a static implementation of the adapters. A typical media browsing application
    171   uses data from an online database or web service. For an example of a browsing application that
    172   uses data retrieved from the web, see the
    173   <a href="http://github.com/googlesamples/androidtv-leanback">Android TV</a> sample app.
    174 </p>
    175 
    176 <h2 id="background">Update the Background</h2>
    177 
    178 <p>
    179   In order to add visual interest to a media-browsing app on TV, you can update the background
    180   image as users browse through content. This technique can make interaction with your app feel
    181   more cinematic and enjoyable for users.
    182 </p>
    183 
    184 <p>
    185   The Leanback support library provides a {@link android.support.v17.leanback.app.BackgroundManager}
    186   class for changing the background of your TV app activity. The following example shows how to
    187   create a simple method for updating the background within your TV app activity:
    188 </p>
    189 
    190 <pre>
    191 protected void updateBackground(Drawable drawable) {
    192     BackgroundManager.getInstance(this).setDrawable(drawable);
    193 }
    194 </pre>
    195 
    196 <p>
    197   Many of the existing media-browse apps automatically update the background as the user navigates
    198   through media listings. In order to do this, you can set up a selection listener to automatically
    199   update the background based on the user's current selection. The following example shows you how
    200   to set up an {@link android.support.v17.leanback.widget.OnItemViewSelectedListener} class to
    201   catch selection events and update the background:
    202 </p>
    203 
    204 <pre>
    205 protected void clearBackground() {
    206     BackgroundManager.getInstance(this).setDrawable(mDefaultBackground);
    207 }
    208 
    209 protected OnItemViewSelectedListener getDefaultItemViewSelectedListener() {
    210     return new OnItemViewSelectedListener() {
    211         &#64;Override
    212         public void onItemSelected(Object item, Row row) {
    213             if (item instanceof Movie ) {
    214                 URI uri = ((Movie)item).getBackdropURI();
    215                 updateBackground(uri);
    216             } else {
    217                 clearBackground();
    218             }
    219         }
    220     };
    221 }
    222 </pre>
    223 
    224 <p class="note">
    225   <strong>Note:</strong> The implementation above is a simple example shown for purposes of
    226   illustration. When creating this function in your own app, you should consider running the
    227   background update action in a separate thread for better performance. In addition, if you are
    228   planning on updating the background in response to users scrolling through items, consider adding
    229   a time to delay a background image update until the user settles on an item. This technique avoids
    230   excessive background image updates.
    231 </p>
    232