3

如何像 YouTube 应用一样制作只有一行可见的 Android TV BrowseFragment 界面?

截图1

这是我的代码的基本结构:

BrowseFragment browseFragment = BrowseFragment.getInstance();

browseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED);
browseFragment.setTitle(getString(R.string.AplicationName));
browseFragment.setBadgeDrawable(ContextCompat.getDrawable(this, R.drawable.badge));

ArrayObjectAdapter rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());


for ( int i = 0; i < itemsCount; ++i ) {

    HeaderItem header = new HeaderItem(i, "Header" + items[i].title);
    ArrayObjectAdapter rowAdapter = new ArrayObjectAdapter(new CardPresenter());

    for ( int i = 0; i < subitemsCount; ++i ) {
        rowAdapter.add(subitems[i]);
    }

    rowsAdapter.add(new ListRow(header, rowAdapter));


}

browseFragment.setAdapter(rowsAdapter);

这会在左侧生成所有标题,但不是一个可见的项目行,而是一个包含所有行的网格,如示例应用程序:

截图2

4

2 回答 2

6

您可以使用此处提供的自定义 BrowseFragment 组件https ://github.com/dextorer/BuildingForAndroidTV

您将能够复制 YouTube 电视应用提供的 UI 结构。


更新

我编写了一个简单的库来扩展 Leanback 并提供更精简(和可靠)的定制。这里是:

沙发

于 2015-06-04T13:04:16.447 回答
3

我所做的是扩展 ListRowPresenter 类(例如:ListVideosRowPresenter),并添加以下代码:

@Override
protected void onSelectLevelChanged(RowPresenter.ViewHolder holder) {
    super.onSelectLevelChanged(holder);

    if (vh.isSelected()){
        vh.getGridView().setVisibility(View.VISIBLE);
    } else {
        vh.getGridView().setVisibility(View.GONE);
    }
}

然后,在 MainFragment 类上,当您创建适配器(HeadersAdapters 和 RowsAdapters)时,您必须使用您的扩展类:

mHeadersAdapter = new ArrayObjectAdapter(new ListVideosRowPresenter());

并且为了避免显示标题,(在 rowsFragment 上)我必须创建两个单独的适配器(一个用于 HeadersFragment,另一个用于 RowsFragment):

        HeaderItem categoryHeader = new HeaderItem(i, MovieList.MOVIE_CATEGORY[i]);
        CustomListRow headersRow = new CustomListRow(categoryHeader, listRowAdapter);
        //I pass null as the header, so no header will be displayed on the RowsFragment
        CustomListRow listRow = new CustomListRow(null, listRowAdapter, MovieList.MOVIE_CATEGORY[i]);
        mRowsAdapter.add(listRow);
        mHeadersAdapter.add(headersRow);

最后在 MainFragment 上编写一个新的 setAdapter 方法(带有两个参数):

public void setAdapter(ObjectAdapter adapterHeaders, ObjectAdapter adapterRows) {
    //this line sets the same adapter for both fragments (headers and rows)
    setAdapter(adapterRows);
    //this line sets the adapter for the HeadersFragment only
    getHeadersFragment().setAdapter(adapterHeaders);
}
于 2017-02-01T13:50:25.407 回答