blob: 8b8fa8b5b4bd27950ceea6489e2959c01e5d2087 [file] [log] [blame]
page.title=DetailFragment
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</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">Creating a Details Activity</a></li>
<li><a href="#item-listener">Listener for Clicked Items</a></li>
</li>
</ol>
</div>
</div>
<p>The media browsing interface classes provided by the
<a href="{@docRoot}preview/tv/start/index.html#tv-libraries">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. This
section discusses how to create a presenter class for media item details and extend the
{@code 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 {@code DetailsFragment}. However, it is possible to avoid creating a second activity
by replacing the current {@code BrowseFragment} with a {@code 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 for by the leanback support library, you use
presenter objects to control the display of data on screen, including media item details. The
framework provides the {@code 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 {@code 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 {
&#64;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 you use the {@code DetailsFragment} class for displaying your media item details, you
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 you created in the
previous section, 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;
&#64;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">Creating a Details Activity</h3>
<p>Fragments such as the {@code 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 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 {@code DetailsFragment}:</p>
<pre>
&lt;!-- file: res/layout/details.xml --&gt;
&lt;fragment xmlns:android="http://schemas.android.com/apk/res/android"
<strong>android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"</strong>
android:id="&#64;+id/details_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/&gt;
</pre>
<p>Next, create an activity class that uses the layout shown in the previous code example:</p>
<pre>
public class DetailsActivity extends Activity
{
&#64;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>
&lt;application&gt;
...
&lt;activity android:name=".DetailsActivity"
android:exported="true"
<strong>android:theme="@style/Theme.Leanback"/&gt;</strong>
&lt;/application&gt;
</pre>
<h3 id="item-listener">Listener for Clicked Items</h3>
<p>After you have implemented the {@code DetailsFragment}, you must 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 {@code OnItemClickedListener} object to the 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 {
...
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
...
// create the media item rows
buildRowsAdapter();
// add a listener for selected items
mBrowseFragment.setOnItemClickedListener(
new OnItemClickedListener() {
&#64;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>