Home | History | Annotate | Download | only in playback
      1 page.title=Building a Details View
      2 page.tags=tv, detailsfragment
      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="#details-presenter">Build a Details Presenter</a></li>
     14     <li><a href="#details-fragment">Extend the Details Fragment</a>
     15     <li><a href="#activity">Create a Details Activity</a></li>
     16     <li><a href="#item-listener">Define a Listener for Clicked Items</a></li>
     17   </ol>
     18 </div>
     19 </div>
     20 
     21 <p>
     22   The media browsing interface classes provided by the <a href=
     23   "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support library</a>
     24   include classes for displaying additional information about a media item, such as a description
     25   or reviews, and for taking action on that item, such as purchasing it or playing its content.
     26 </p>
     27 
     28 <p>
     29   This lesson discusses how to create a presenter class for media item details, and how to extend
     30   the {@link android.support.v17.leanback.app.DetailsFragment} class to implement a details view
     31   for a media item when it is selected by a user.
     32 </p>
     33 
     34 <p class="note">
     35   <strong>Note:</strong> The implementation example shown here uses an additional activity to
     36   contain the {@link android.support.v17.leanback.app.DetailsFragment}. However, it is possible to
     37   avoid creating a second activity by replacing the current {@link
     38   android.support.v17.leanback.app.BrowseFragment} with a {@link
     39   android.support.v17.leanback.app.DetailsFragment} within the <em>same</em> activity using
     40   fragment transactions. For more information on using fragment transactions, see the <a href=
     41   "{@docRoot}training/basics/fragments/fragment-ui.html#Replace">Building a Dynamic UI with
     42   Fragments</a> training.
     43 </p>
     44 
     45 
     46 <h2 id="details-presenter">Build a Details Presenter</h2>
     47 
     48 <p>
     49   In the media browsing framework provided by the leanback library, you use presenter
     50   objects to control the display of data on screen, including media item details. The framework
     51   provides the {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}
     52   class for this purpose, which is a nearly complete implementation of the presenter for media item
     53   details. All you have to do is implement the {@link
     54   android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter#onBindDescription
     55   onBindDescription()} method to bind the view fields to your data objects, as shown in the
     56   following code sample:
     57 </p>
     58 
     59 <pre>
     60 public class DetailsDescriptionPresenter
     61         extends AbstractDetailsDescriptionPresenter {
     62 
     63     &#64;Override
     64     protected void onBindDescription(ViewHolder viewHolder, Object itemData) {
     65         MyMediaItemDetails details = (MyMediaItemDetails) itemData;
     66         // In a production app, the itemData object contains the information
     67         // needed to display details for the media item:
     68         // viewHolder.getTitle().setText(details.getShortTitle());
     69 
     70         // Here we provide static data for testing purposes:
     71         viewHolder.getTitle().setText(itemData.toString());
     72         viewHolder.getSubtitle().setText("2014   Drama   TV-14");
     73         viewHolder.getBody().setText("Lorem ipsum dolor sit amet, consectetur "
     74                 + "adipisicing elit, sed do eiusmod tempor incididunt ut labore "
     75                 + " et dolore magna aliqua. Ut enim ad minim veniam, quis "
     76                 + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
     77                 + "commodo consequat.");
     78     }
     79 }
     80 </pre>
     81 
     82 
     83 <h2 id="details-fragment">Extend the Details Fragment</h2>
     84 
     85 <p>
     86   When using the {@link android.support.v17.leanback.app.DetailsFragment} class for displaying
     87   your media item details, extend that class to provide additional content such as a preview
     88   image and actions for the media item. You can also provide additional content, such as a list of
     89   related media items.
     90 </p>
     91 
     92 <p>
     93   The following example code demonstrates how to use the presenter class shown in the
     94   previous section, to add a preview image and actions for the media item being viewed. This example
     95   also shows the addition of a related media items row, which appears below the details listing.
     96 </p>
     97 
     98 <pre>
     99 public class MediaItemDetailsFragment extends DetailsFragment {
    100     private static final String TAG = "MediaItemDetailsFragment";
    101     private ArrayObjectAdapter mRowsAdapter;
    102 
    103     &#64;Override
    104     public void onCreate(Bundle savedInstanceState) {
    105         Log.i(TAG, "onCreate");
    106         super.onCreate(savedInstanceState);
    107 
    108         buildDetails();
    109     }
    110 
    111     private void buildDetails() {
    112         ClassPresenterSelector selector = new ClassPresenterSelector();
    113         // Attach your media item details presenter to the row presenter:
    114         FullWidthDetailsOverviewRowPresenter rowPresenter =
    115             new FullWidthDetailsOverviewRowPresenter(
    116                 new DetailsDescriptionPresenter());
    117 
    118         selector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
    119         selector.addClassPresenter(ListRow.class,
    120                 new ListRowPresenter());
    121         mRowsAdapter = new ArrayObjectAdapter(selector);
    122 
    123         Resources res = getActivity().getResources();
    124         DetailsOverviewRow detailsOverview = new DetailsOverviewRow(
    125                 "Media Item Details");
    126 
    127         // Add images and action buttons to the details view
    128         detailsOverview.setImageDrawable(res.getDrawable(R.drawable.jelly_beans));
    129         detailsOverview.addAction(new Action(1, "Buy $9.99"));
    130         detailsOverview.addAction(new Action(2, "Rent $2.99"));
    131         mRowsAdapter.add(detailsOverview);
    132 
    133         // Add a Related items row
    134         ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
    135                 new StringPresenter());
    136         listRowAdapter.add("Media Item 1");
    137         listRowAdapter.add("Media Item 2");
    138         listRowAdapter.add("Media Item 3");
    139         HeaderItem header = new HeaderItem(0, "Related Items", null);
    140         mRowsAdapter.add(new ListRow(header, listRowAdapter));
    141 
    142         setAdapter(mRowsAdapter);
    143     }
    144 }
    145 </pre>
    146 
    147 
    148 <h3 id="activity">Create a Details Activity</h3>
    149 
    150 <p>
    151   Fragments such as the {@link android.support.v17.leanback.app.DetailsFragment} must be contained
    152   within an activity in order to be used for display. Creating an activity for your details view,
    153   separate from the browse activity, enables you to invoke your details view using an
    154   {@link android.content.Intent}. This
    155   section explains how to build an activity to contain your implementation of the detail view for
    156   your media items.
    157 </p>
    158 
    159 <p>
    160   Start creating the details activity by building a layout that references your implementation of
    161   the {@link android.support.v17.leanback.app.DetailsFragment}:
    162 </p>
    163 
    164 <pre>
    165 &lt;!-- file: res/layout/details.xml --&gt;
    166 
    167 &lt;fragment xmlns:android="http://schemas.android.com/apk/res/android"
    168     <strong>android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"</strong>
    169     android:id="&#64;+id/details_fragment"
    170     android:layout_width="match_parent"
    171     android:layout_height="match_parent"
    172 /&gt;
    173 </pre>
    174 
    175 <p>
    176   Next, create an activity class that uses the layout shown in the previous code example:
    177 </p>
    178 
    179 <pre>
    180 public class DetailsActivity extends Activity
    181 {
    182     &#64;Override
    183     public void onCreate(Bundle savedInstanceState) {
    184         super.onCreate(savedInstanceState);
    185         <strong>setContentView(R.layout.details);</strong>
    186     }
    187 }
    188 </pre>
    189 
    190 <p>
    191   Finally, add this new activity to the manifest. Remember to apply the Leanback theme to ensure
    192   that the user interface is consistent with the media browse activity:
    193 </p>
    194 
    195 <pre>
    196 &lt;application&gt;
    197   ...
    198 
    199   &lt;activity android:name=".DetailsActivity"
    200     android:exported="true"
    201     <strong>android:theme="@style/Theme.Leanback"/&gt;</strong>
    202 
    203 &lt;/application&gt;
    204 </pre>
    205 
    206 
    207 <h3 id="item-listener">Define a Listener for Clicked Items</h3>
    208 
    209 <p>
    210   After you have implemented the {@link android.support.v17.leanback.app.DetailsFragment},
    211   modify your main media browsing view to move to your details view when a user clicks on a media
    212   item. In order to enable this behavior, add an
    213   {@link android.support.v17.leanback.widget.OnItemViewClickedListener} object to the
    214   {@link android.support.v17.leanback.app.BrowseFragment} that fires an intent to start the item
    215   details activity.
    216 </p>
    217 
    218 <p>
    219   The following example shows how to implement a listener to start the details view when a user
    220   clicks a media item in the main media browsing activity:
    221 </p>
    222 
    223 <pre>
    224 public class BrowseMediaActivity extends Activity {
    225     ...
    226 
    227     &#64;Override
    228     protected void onCreate(Bundle savedInstanceState) {
    229         ...
    230 
    231         // create the media item rows
    232         buildRowsAdapter();
    233 
    234         // add a listener for selected items
    235         mBrowseFragment.OnItemViewClickedListener(
    236             new OnItemViewClickedListener() {
    237                 &#64;Override
    238                 public void onItemClicked(Object item, Row row) {
    239                     System.out.println("Media Item clicked: " + item.toString());
    240                     Intent intent = new Intent(BrowseMediaActivity.this,
    241                             DetailsActivity.class);
    242                     // pass the item information
    243                     intent.getExtras().putLong("id", item.getId());
    244                     startActivity(intent);
    245                 }
    246             });
    247     }
    248 }
    249 </pre>
    250