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 @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 @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 <!-- file: res/layout/details.xml --> 165 166 <fragment xmlns:android="http://schemas.android.com/apk/res/android" 167 <strong>android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"</strong> 168 android:id="@+id/details_fragment" 169 android:layout_width="match_parent" 170 android:layout_height="match_parent" 171 /> 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 @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 <application> 196 ... 197 198 <activity android:name=".DetailsActivity" 199 android:exported="true" 200 <strong>android:theme="@style/Theme.Leanback"/></strong> 201 202 </application> 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 @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 @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