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         DetailsOverviewRowPresenter rowPresenter =
    115             new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
    116 
    117         selector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
    118         selector.addClassPresenter(ListRow.class,
    119                 new ListRowPresenter());
    120         mRowsAdapter = new ArrayObjectAdapter(selector);
    121 
    122         Resources res = getActivity().getResources();
    123         DetailsOverviewRow detailsOverview = new DetailsOverviewRow(
    124                 "Media Item Details");
    125 
    126         // Add images and action buttons to the details view
    127         detailsOverview.setImageDrawable(res.getDrawable(R.drawable.jelly_beans));
    128         detailsOverview.addAction(new Action(1, "Buy $9.99"));
    129         detailsOverview.addAction(new Action(2, "Rent $2.99"));
    130         mRowsAdapter.add(detailsOverview);
    131 
    132         // Add a Related items row
    133         ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
    134                 new StringPresenter());
    135         listRowAdapter.add("Media Item 1");
    136         listRowAdapter.add("Media Item 2");
    137         listRowAdapter.add("Media Item 3");
    138         HeaderItem header = new HeaderItem(0, "Related Items", null);
    139         mRowsAdapter.add(new ListRow(header, listRowAdapter));
    140 
    141         setAdapter(mRowsAdapter);
    142     }
    143 }
    144 </pre>
    145 
    146 
    147 <h3 id="activity">Create a Details Activity</h3>
    148 
    149 <p>
    150   Fragments such as the {@link android.support.v17.leanback.app.DetailsFragment} must be contained
    151   within an activity in order to be used for display. Creating an activity for your details view,
    152   separate from the browse activity, enables you to invoke your details view using an
    153   {@link android.content.Intent}. This
    154   section explains how to build an activity to contain your implementation of the detail view for
    155   your media items.
    156 </p>
    157 
    158 <p>
    159   Start creating the details activity by building a layout that references your implementation of
    160   the {@link android.support.v17.leanback.app.DetailsFragment}:
    161 </p>
    162 
    163 <pre>
    164 &lt;!-- file: res/layout/details.xml --&gt;
    165 
    166 &lt;fragment xmlns:android="http://schemas.android.com/apk/res/android"
    167     <strong>android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"</strong>
    168     android:id="&#64;+id/details_fragment"
    169     android:layout_width="match_parent"
    170     android:layout_height="match_parent"
    171 /&gt;
    172 </pre>
    173 
    174 <p>
    175   Next, create an activity class that uses the layout shown in the previous code example:
    176 </p>
    177 
    178 <pre>
    179 public class DetailsActivity extends Activity
    180 {
    181     &#64;Override
    182     public void onCreate(Bundle savedInstanceState) {
    183         super.onCreate(savedInstanceState);
    184         <strong>setContentView(R.layout.details);</strong>
    185     }
    186 }
    187 </pre>
    188 
    189 <p>
    190   Finally, add this new activity to the manifest. Remember to apply the Leanback theme to ensure
    191   that the user interface is consistent with the media browse activity:
    192 </p>
    193 
    194 <pre>
    195 &lt;application&gt;
    196   ...
    197 
    198   &lt;activity android:name=".DetailsActivity"
    199     android:exported="true"
    200     <strong>android:theme="@style/Theme.Leanback"/&gt;</strong>
    201 
    202 &lt;/application&gt;
    203 </pre>
    204 
    205 
    206 <h3 id="item-listener">Define a Listener for Clicked Items</h3>
    207 
    208 <p>
    209   After you have implemented the {@link android.support.v17.leanback.app.DetailsFragment},
    210   modify your main media browsing view to move to your details view when a user clicks on a media
    211   item. In order to enable this behavior, add an
    212   {@link android.support.v17.leanback.widget.OnItemViewClickedListener} object to the
    213   {@link android.support.v17.leanback.app.BrowseFragment} that fires an intent to start the item
    214   details activity.
    215 </p>
    216 
    217 <p>
    218   The following example shows how to implement a listener to start the details view when a user
    219   clicks a media item in the main media browsing activity:
    220 </p>
    221 
    222 <pre>
    223 public class BrowseMediaActivity extends Activity {
    224     ...
    225 
    226     &#64;Override
    227     protected void onCreate(Bundle savedInstanceState) {
    228         ...
    229 
    230         // create the media item rows
    231         buildRowsAdapter();
    232 
    233         // add a listener for selected items
    234         mBrowseFragment.OnItemViewClickedListener(
    235             new OnItemViewClickedListener() {
    236                 &#64;Override
    237                 public void onItemClicked(Object item, Row row) {
    238                     System.out.println("Media Item clicked: " + item.toString());
    239                     Intent intent = new Intent(BrowseMediaActivity.this,
    240                             DetailsActivity.class);
    241                     // pass the item information
    242                     intent.getExtras().putLong("id", item.getId());
    243                     startActivity(intent);
    244                 }
    245             });
    246     }
    247 }
    248 </pre>
    249