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