1page.title=Building a Details View
2page.tags=tv, detailsfragment
3helpoutsWidget=true
4
5trainingnavtop=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>
60public 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>
99public 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>
179public 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>
223public 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