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