创建目录浏览器

编写:huanglizhuo - 原文:http://developer.android.com/training/tv/playback/browse.html

在TV上运行的 多媒体应用得允许用户浏览,选择和播放它所提供的内容。目录浏览器的用户体验要简单和直观,以及赏心悦目,引人入胜。

这节课讨论如何使用的V17 Leanback库提供的类来实现用户界面,用于从您的应用程序的媒体目录浏览音乐或视频。

创建一个目录布局

leanback 类库中的BrowseFragment允许您用最少的代码创建一个用于按行浏览的主布局 ,下面的例子将演示如何创建包含BrowseFragment的布局

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical"
  5. >
  6. <fragment
  7. android:name="android.support.v17.leanback.app.BrowseFragment"
  8. android:id="@+id/browse_fragment"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. />
  12. </LinearLayout>

为了使 activity 工作,需要在布局中取回BrowseFragment的元素。使用这个类中的方法设置显示参数,如图标,标题,以及该类别是否可用。下面的代码简单的演示了怎样设置BrowseFragment布局参数:

  1. public class BrowseMediaActivity extends Activity {
  2. public static final String TAG ="BrowseActivity";
  3. protected BrowseFragment mBrowseFragment;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.browse_fragment);
  8. final FragmentManager fragmentManager = getFragmentManager();
  9. mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById(
  10. R.id.browse_fragment);
  11. // Set display parameters for the BrowseFragment
  12. mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED);
  13. mBrowseFragment.setTitle(getString(R.string.app_name));
  14. mBrowseFragment.setBadgeDrawable(getResources().getDrawable(
  15. R.drawable.ic_launcher));
  16. mBrowseFragment.setBrowseParams(params);
  17. }
  18. }

显示媒体列表

BrowseFragment允许您定义和使用 adapter 和presenter 定义显示可浏览媒体内容类别和媒体项目。Adapters 允许我们连接本地或网络数据资源。Presenters操控的媒体项目的数据,并提供布局信息在屏幕上显示的项目。

下面的示例代码演示了一个为显示字符串数据的Presenters的实现

  1. public class StringPresenter extends Presenter {
  2. private static final String TAG = "StringPresenter";
  3. public ViewHolder onCreateViewHolder(ViewGroup parent) {
  4. TextView textView = new TextView(parent.getContext());
  5. textView.setFocusable(true);
  6. textView.setFocusableInTouchMode(true);
  7. textView.setBackground(
  8. parent.getContext().getResources().getDrawable(R.drawable.text_bg));
  9. return new ViewHolder(textView);
  10. }
  11. public void onBindViewHolder(ViewHolder viewHolder, Object item) {
  12. ((TextView) viewHolder.view).setText(item.toString());
  13. }
  14. public void onUnbindViewHolder(ViewHolder viewHolder) {
  15. // no op
  16. }
  17. }

当我们已经为我们的媒体项目构建了一个Presenter类,我们可以为BrowseFragment建立并添加一个适配器并在屏幕上显示这些媒体项目。下面的示例代码演示了如何用StringPresenter类构造一个类别和项目适配器:

  1. private ArrayObjectAdapter mRowsAdapter;
  2. private static final int NUM_ROWS = 4;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. ...
  6. buildRowsAdapter();
  7. }
  8. private void buildRowsAdapter() {
  9. mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
  10. for (int i = 0; i < NUM_ROWS; ++i) {
  11. ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
  12. new StringPresenter());
  13. listRowAdapter.add("Media Item 1");
  14. listRowAdapter.add("Media Item 2");
  15. listRowAdapter.add("Media Item 3");
  16. HeaderItem header = new HeaderItem(i, "Category " + i, null);
  17. mRowsAdapter.add(new ListRow(header, listRowAdapter));
  18. }
  19. mBrowseFragment.setAdapter(mRowsAdapter);
  20. }

这个例子显示了静态实现适配器。典型的媒体浏览器使用网络数据库或网络服务。使用从网络取回的数据做的媒体浏览器,参看例子Android TV

更新背景

为了给媒体浏览应用增加视觉趣味,我们可以在用户浏览的内容时更新背景图片。这种技术可以让我们的应用程序的互动感倍增。

Leanback库提供了BackgroundManager类为我们的TV应用的activity更换背景。下面的例子演示了如何创建一个简单的方法更换背景:

  1. protected void updateBackground(Drawable drawable) {
  2. BackgroundManager.getInstance(this).setDrawable(drawable);
  3. }

许多现有的媒体浏览应用在用户浏览媒体列表自动更新的背景。为了做到这一点,我们可以设置一个选择监听器,根据用户的当前选择自动更新背景。下面的例子演示了如何建立一个OnItemViewSelectedListener监听选择事件并更新背景:

  1. protected void clearBackground() {
  2. BackgroundManager.getInstance(this).setDrawable(mDefaultBackground);
  3. }
  4. protected OnItemViewSelectedListener getDefaultItemViewSelectedListener() {
  5. return new OnItemViewSelectedListener() {
  6. @Override
  7. public void onItemSelected(Object item, Row row) {
  8. if (item instanceof Movie ) {
  9. URI uri = ((Movie)item).getBackdropURI();
  10. updateBackground(uri);
  11. } else {
  12. clearBackground();
  13. }
  14. }
  15. };
  16. }

注意:以上的示例是为了简单。当我们在自己的应用程序创建这个功能,我们应该考虑运行在一个单独的线程在后台更新操作获得更好的性能。此外,如果我们正计划在用户触发项目滚动时更新背景,考虑增加一个时延,直到用户停止操作时再更新背景图像。这样可以避免过多的背景图片的更新。


下一节:提供一个卡片View >