1 page.title=Creating a Catalog Browser 2 page.tags=tv, browsefragment, presenter, backgroundmanager 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="#layout">Create a Media Browse Layout</a></li> 14 <li><a href="#lists">Display Media Lists</a></li> 15 <li><a href="#background">Update the Background</a></li> 16 </ol> 17 18 </div> 19 </div> 20 21 <p> 22 Media apps that run on TV need to allow users to browse its content offerings, make a 23 selection, and start playing content. The content browsing experience for apps of this type 24 should be simple and intuitive, as well as visually pleasing and engaging. 25 </p> 26 27 <p> 28 This lesson discusses how to use the classes provided by the <a href= 29 "{@docRoot}tools/support-library/features.html#v17-leanback">v17 leanback support library</a> to 30 implement a user interface for browsing music or videos from your app's media catalog. 31 </p> 32 33 34 <h2 id="layout">Create a Media Browse Layout</h2> 35 36 <p> 37 The {@link android.support.v17.leanback.app.BrowseFragment} class in the leanback library 38 allows you to create a primary layout for browsing categories and rows of media items with a 39 minimum of code. The following example shows how to create a layout that contains a {@link 40 android.support.v17.leanback.app.BrowseFragment}: 41 </p> 42 43 <pre> 44 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 45 android:layout_width="match_parent" 46 android:layout_height="match_parent" 47 android:orientation="vertical" 48 > 49 50 <fragment 51 <strong>android:name="android.support.v17.leanback.app.BrowseFragment"</strong> 52 android:id="@+id/browse_fragment" 53 android:layout_width="match_parent" 54 android:layout_height="match_parent" 55 /> 56 </LinearLayout> 57 </pre> 58 59 <p> 60 In order to work with this layout in an activity, retrieve the {@link 61 android.support.v17.leanback.app.BrowseFragment} element from the layout. Use the methods in this 62 class to set display parameters such as the icon, title, and whether category headers are enabled. 63 The following code sample demonstrates how to set the layout parameters for a {@link 64 android.support.v17.leanback.app.BrowseFragment} in a layout: 65 </p> 66 67 <pre> 68 public class BrowseMediaActivity extends Activity { 69 70 public static final String TAG ="BrowseActivity"; 71 72 protected BrowseFragment mBrowseFragment; 73 74 @Override 75 protected void onCreate(Bundle savedInstanceState) { 76 super.onCreate(savedInstanceState); 77 setContentView(R.layout.browse_fragment); 78 79 final FragmentManager fragmentManager = getFragmentManager(); 80 <strong>mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById( 81 R.id.browse_fragment);</strong> 82 83 // Set display parameters for the BrowseFragment 84 mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED); 85 mBrowseFragment.setTitle(getString(R.string.app_name)); 86 mBrowseFragment.setBadgeDrawable(getResources().getDrawable( 87 R.drawable.ic_launcher)); 88 mBrowseFragment.setBrowseParams(params); 89 90 } 91 } 92 </pre> 93 94 95 <h2 id="lists">Displaying Media Lists</h2> 96 97 <p> 98 The {@link android.support.v17.leanback.app.BrowseFragment} allows you to define and display 99 browsable media content categories and media items from a media catalog using adapters and 100 presenters. Adapters enable you to connect to local or online data sources that contain your 101 media catalog information. Presenters hold data about media items and provide layout information 102 for displaying an item on screen. 103 </p> 104 105 <p> 106 The following example code shows an implementation of a {@link 107 android.support.v17.leanback.widget.Presenter} for displaying string data: 108 </p> 109 110 <pre> 111 public class StringPresenter extends Presenter { 112 private static final String TAG = "StringPresenter"; 113 114 public ViewHolder onCreateViewHolder(ViewGroup parent) { 115 TextView textView = new TextView(parent.getContext()); 116 textView.setFocusable(true); 117 textView.setFocusableInTouchMode(true); 118 textView.setBackground( 119 parent.getContext().getResources().getDrawable(R.drawable.text_bg)); 120 return new ViewHolder(textView); 121 } 122 123 public void onBindViewHolder(ViewHolder viewHolder, Object item) { 124 ((TextView) viewHolder.view).setText(item.toString()); 125 } 126 127 public void onUnbindViewHolder(ViewHolder viewHolder) { 128 // no op 129 } 130 } 131 </pre> 132 133 <p> 134 Once you have constructed a presenter class for your media items, you can build and attach an 135 adapter to the {@link android.support.v17.leanback.app.BrowseFragment} to display those items on 136 screen for browsing by the user. The following example code demonstrates how to construct an 137 adapter to display categories and items in those categories using the {@code StringPresenter} 138 class shown in the previous code example: 139 </p> 140 141 <pre> 142 private ArrayObjectAdapter mRowsAdapter; 143 private static final int NUM_ROWS = 4; 144 145 @Override 146 protected void onCreate(Bundle savedInstanceState) { 147 ... 148 149 buildRowsAdapter(); 150 } 151 152 private void buildRowsAdapter() { 153 mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); 154 155 for (int i = 0; i < NUM_ROWS; ++i) { 156 ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter( 157 new StringPresenter()); 158 listRowAdapter.add("Media Item 1"); 159 listRowAdapter.add("Media Item 2"); 160 listRowAdapter.add("Media Item 3"); 161 HeaderItem header = new HeaderItem(i, "Category " + i, null); 162 mRowsAdapter.add(new ListRow(header, listRowAdapter)); 163 } 164 165 mBrowseFragment.setAdapter(mRowsAdapter); 166 } 167 </pre> 168 169 <p> 170 This example shows a static implementation of the adapters. A typical media browsing application 171 uses data from an online database or web service. For an example of a browsing application that 172 uses data retrieved from the web, see the 173 <a href="http://github.com/googlesamples/androidtv-leanback">Android TV</a> sample app. 174 </p> 175 176 <h2 id="background">Update the Background</h2> 177 178 <p> 179 In order to add visual interest to a media-browsing app on TV, you can update the background 180 image as users browse through content. This technique can make interaction with your app feel 181 more cinematic and enjoyable for users. 182 </p> 183 184 <p> 185 The Leanback support library provides a {@link android.support.v17.leanback.app.BackgroundManager} 186 class for changing the background of your TV app activity. The following example shows how to 187 create a simple method for updating the background within your TV app activity: 188 </p> 189 190 <pre> 191 protected void updateBackground(Drawable drawable) { 192 BackgroundManager.getInstance(this).setDrawable(drawable); 193 } 194 </pre> 195 196 <p> 197 Many of the existing media-browse apps automatically update the background as the user navigates 198 through media listings. In order to do this, you can set up a selection listener to automatically 199 update the background based on the user's current selection. The following example shows you how 200 to set up an {@link android.support.v17.leanback.widget.OnItemViewSelectedListener} class to 201 catch selection events and update the background: 202 </p> 203 204 <pre> 205 protected void clearBackground() { 206 BackgroundManager.getInstance(this).setDrawable(mDefaultBackground); 207 } 208 209 protected OnItemViewSelectedListener getDefaultItemViewSelectedListener() { 210 return new OnItemViewSelectedListener() { 211 @Override 212 public void onItemSelected(Object item, Row row) { 213 if (item instanceof Movie ) { 214 URI uri = ((Movie)item).getBackdropURI(); 215 updateBackground(uri); 216 } else { 217 clearBackground(); 218 } 219 } 220 }; 221 } 222 </pre> 223 224 <p class="note"> 225 <strong>Note:</strong> The implementation above is a simple example shown for purposes of 226 illustration. When creating this function in your own app, you should consider running the 227 background update action in a separate thread for better performance. In addition, if you are 228 planning on updating the background in response to users scrolling through items, consider adding 229 a time to delay a background image update until the user settles on an item. This technique avoids 230 excessive background image updates. 231 </p> 232