Android TVAndroidTV开发Android TV开发

[译]构建BrowseFragment--Android TV

2017-04-13  本文已影响4296人  wenju_song

版权声明:本文为博主原创翻译文章,转载请注明出处。

推荐:
欢迎关注我创建的Android TV 简书专题,会定期给大家分享一些AndroidTv相关的内容:
http://www.jianshu.com/c/37efc6e9799b


GridItemPresenter.png

在本章中,我们将实现标题和可选对象(所谓的“card”)的组合。 但是在实际实现之前,了解BrowseFragment的构造是很好的。 你还可以自己阅读sdk(android / support / v17 / leanback / app /)中的源代码。
让我们开始使用Android TV示例应用程序进行解释。 启动应用程序时,内容将以网格结构对齐。 左侧的每个标题都有一个内容行,这个标题 - 内容行关系是一对一的。 这个“标题+内容行”组合由ListRow表示。 BrowseFragment的主体是一组ListRow(我将在本文中使用术语RowsAdapter)。
在下图中,ListRow由蓝色圆圈表示。 而一个蓝色方块是一个RowsAdapter,它是蓝色圆圈的集合。


一组ListRow构造RowsAdapter,它是BrowseFragment的主体UI。

总而言之,

ArrayObjectAdapter(RowsAdapter)←一组ListRow
ListRow = HeaderItem + ArrayObjectAdapter(RowAdapter)
ArrayObjectAdapter(RowAdapter)←一组Object(CardInfo / Item)

Presenter 类

card的设计由Presenter类确定。 Presenter定义如何显示/显示cardInfo。 Presenter类本身就是一个抽象类,所以你需要扩展这个类,以适应你应用程序的UI设计。
当扩展Presenter时,需要至少覆盖3种方法。

 onCreateViewHolder(Viewgroup parent)
 onBindViewHolder(ViewHolder viewHolder,Object cardInfo / item)
 onUnbindViewHolder(ViewHolder viewHolder)

类似与RecyclerView的onCreateViewHolder和onBindViewHolder。
Presenter具有内部类ViewHolder,它具有对View的引用。 可以通过viewHolder在特定事件(onBind,onUnbind等)监听器回调方法访问View。

实现HeadersFragment & RowsFragment (GridItemPresenter)

这里,我们将实现GridItemPresenter类。
在此示例应用程序中,Object(CardInfo / item)是String类型,viewHolder保存TextView引用以显示此String。

视图的布局在onCreateViewHolder()中定义。
onBindViewHolder()的参数,我们可以访问由onCreateViewHolder创建的viewHolder以及存储card信息的Object(CardInfo / item)(在本示例中只是一个String)。

    private class GridItemPresenter extends Presenter {
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent) {
            TextView view = new TextView(parent.getContext());
            view.setLayoutParams(new ViewGroup.LayoutParams(GRID_ITEM_WIDTH, GRID_ITEM_HEIGHT));
            view.setFocusable(true);
            view.setFocusableInTouchMode(true);
            view.setBackgroundColor(getResources().getColor(R.color.default_background));
            view.setTextColor(Color.WHITE);
            view.setGravity(Gravity.CENTER);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(ViewHolder viewHolder, Object item) {
            ((TextView) viewHolder.view).setText((String) item);
        }

        @Override
        public void onUnbindViewHolder(ViewHolder viewHolder) {

        }
    }

}

定义自己的Presenter后,只需要在Activity的开始时设置RowsAdapter。 您可以在MainFragment中的onActivityCreated()中执行此操作,

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        Log.i(TAG, "onActivityCreated");
        super.onActivityCreated(savedInstanceState);

        setupUIElements();

        loadRows();
    }

    ...

    private void loadRows() {
        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());

        /* GridItemPresenter */
        HeaderItem gridItemPresenterHeader = new HeaderItem(0, "GridItemPresenter");

        GridItemPresenter mGridPresenter = new GridItemPresenter();
        ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(mGridPresenter);
        gridRowAdapter.add("ITEM 1");
        gridRowAdapter.add("ITEM 2");
        gridRowAdapter.add("ITEM 3");
        mRowsAdapter.add(new ListRow(gridItemPresenterHeader, gridRowAdapter));

        /* set */
        setAdapter(mRowsAdapter);
    }

所以MainFragment的全部源代码将是:

package com.songwenju.androidtvapptutoria;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v17.leanback.app.BrowseFragment;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.Presenter;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * songwenju on 17-3-27 : 13 : 38.
 * 邮箱:songwenju@outlook.com
 */

public class MainFragment extends BrowseFragment {

    private ArrayObjectAdapter mRowsAdapter;
    private static final int GRID_ITEM_WIDTH = 300;
    private static final int GRID_ITEM_HEIGHT = 200;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        LogUtil.i(this, "MainFragment.onActivityCreated.");
        super.onActivityCreated(savedInstanceState);
        setupUIElements();

        loadRows();
    }

    private void loadRows() {
        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());

        /* GridItemPresenter */
        HeaderItem gridItemPresenterHeader = new HeaderItem(0, "GridItemPresenter");

        GridItemPresenter gridItemPresenter = new GridItemPresenter();
        ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridItemPresenter);
        gridRowAdapter.add("ITEM 1");
        gridRowAdapter.add("ITEM 2");
        gridRowAdapter.add("ITEM 3");

        mRowsAdapter.add(new ListRow(gridItemPresenterHeader, gridRowAdapter));
        /* set */
        setAdapter(mRowsAdapter);

    }

    private void setupUIElements() {

//        setBadgeDrawable(getActivity()
//                .getResources()
//                .getDrawable(R.drawable.app_icon_your_company));//设置图标

        setTitle("Hello Android TV!");  //设置title

        //HEADERS_ENABLED 显示左侧导航栏,HEADERS_DISABLED 不显示 HEADERS_HIDDEN 隐藏,到边缘按左键还能显示
        setHeadersState(HEADERS_HIDDEN);
        setHeadersTransitionOnBackEnabled(true);

        // 设置快速导航(或 headers) 背景色
        setBrandColor(getResources().getColor(R.color.fastlane_background));
        // 设置搜索的颜色
        setSearchAffordanceColor(getResources().getColor(R.color.search_opaque));
    }


    private class GridItemPresenter extends Presenter {

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent) {
            TextView view = new TextView(parent.getContext());
            view.setLayoutParams(new ViewGroup.LayoutParams(GRID_ITEM_WIDTH,GRID_ITEM_HEIGHT));
            view.setFocusable(true);
            view.setFocusableInTouchMode(true);
            view.setBackgroundColor(getResources().getColor(R.color.default_background));
            view.setTextColor(Color.WHITE);
            view.setGravity(Gravity.CENTER);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(ViewHolder viewHolder, Object item) {
            ((TextView)viewHolder.view).setText((String)item);
        }

        @Override
        public void onUnbindViewHolder(ViewHolder viewHolder) {

        }
    }
}

在colors.xml文件中添加:

 <color name="default_background">#3d3d3d</color>

这样MainFragment可以引用背景颜色设置。

构建和运行

现在你可以看到标题和内容组合被实现了。


GridItemPresenter1-800x450.png GridItemPresenter2.png

请注意,我们只定义了Presenter,并加载了要显示的项目。 其他动画,例如 当您选择项目时,会变大,已在SDK中实现。 所以即使是非设计师,很容易为Android TV应用程序制作一定程度的UI。
源代码被上传到github

看到下一篇文章,如何使用Presenter和ViewHolder? - Android TV应用程序使用教程三,对于使用ImageCardView的CardPresenter实现来呈现具有主图像,标题和子文本的卡。
关注微信公众号,定期为你推荐移动开发相关文章。

songwenju
上一篇下一篇

猜你喜欢

热点阅读