美文网首页Android TVAndroidTV开发Android TV开发
[译]构建BrowseFragment--Android TV

[译]构建BrowseFragment--Android TV

作者: wenju_song | 来源:发表于2017-04-13 15:53 被阅读4296次

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

    推荐:
    欢迎关注我创建的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

    相关文章

      网友评论

        本文标题:[译]构建BrowseFragment--Android TV

        本文链接:https://www.haomeiwen.com/subject/fwqjottx.html