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