• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Creating a Catalog Browser
2page.tags="browsefragment","presenter","backgroundmanager"
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="#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&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
44  android:layout_width=&quot;match_parent&quot;
45  android:layout_height=&quot;match_parent&quot;
46  android:orientation=&quot;vertical&quot;
47  &gt;
48
49  &lt;fragment
50      <strong>android:name="android.support.v17.leanback.app.BrowseFragment"</strong>
51      android:id=&quot;@+id/browse_fragment&quot;
52      android:layout_width=&quot;match_parent&quot;
53      android:layout_height=&quot;match_parent&quot;
54      /&gt;
55&lt;/LinearLayout&gt;
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>
67public class BrowseMediaActivity extends Activity {
68
69    public static final String TAG ="BrowseActivity";
70
71    protected BrowseFragment mBrowseFragment;
72
73    &#64;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>
110public 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>
141private ArrayObjectAdapter mRowsAdapter;
142private static final int NUM_ROWS = 4;
143
144&#64;Override
145protected void onCreate(Bundle savedInstanceState) {
146    ...
147
148    buildRowsAdapter();
149}
150
151private void buildRowsAdapter() {
152    mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
153
154    for (int i = 0; i &lt; 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>
190protected 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>
204protected void clearBackground() {
205    BackgroundManager.getInstance(this).setDrawable(mDefaultBackground);
206}
207
208protected OnItemViewSelectedListener getDefaultItemViewSelectedListener() {
209    return new OnItemViewSelectedListener() {
210        &#64;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