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