[译]构建BrowseFragment--Android TV
版权声明:本文为博主原创翻译文章,转载请注明出处。
推荐:
欢迎关注我创建的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实现来呈现具有主图像,标题和子文本的卡。
关注微信公众号,定期为你推荐移动开发相关文章。