2019独角兽企业重金招聘Python工程师标准>>>
本人由于最近一段时间很忙,一直都没有更新 android tv的开源库了,因为技术的更新迭代,TV开发的库已经升级为Leanback + 移动边框等等东西,希望这篇文章能激发你对于 Android TV 更多的想法,水平有限,互相学习,谢谢.
Android tv 开源社区地址:https://gitee.com/kumei (欢迎加入)
Android tv 开源社区收集的库:https://gitee.com/kumei/Android_tv_libs
Leanback demo地址: https://github.com/googlesamples/leanback-showcase
入门文章: https://www.jianshu.com/p/d575e0c7bd59
▌Leanback
谷歌官方的 demo 中 是这样的,那样的… …,都是围绕 Fragment展开的.
如果真不想用谷歌自带的Fragment,想单独使用,或者写自己的标题栏或者多级菜单,这么办?
先来一张图片,类似下图的布局确实很酷炫.
如何使用 Leanback 的库
- 直接Adnroid studio 导入,版本有差异化,不懂的百度查,github看.
- https://github.com/FrozenFreeFall/Leanback_tv_widget 这里我直接使用 从v14导出来的Leanback.
使用Leanback弄出下面的界面
demo: https://gitee.com/kumei/Launcher 代码有点乱,后续整理.
我感觉不用分析什么Leabnack,也不用讲解一大堆如何使用,我下面就直接贴代码,并注释吧.
先来分析下上图,标题栏 + ViewPager(包含多个Fragment)
如果标题栏使用 Recyclerview 或者横向的布局,你都要处理焦点记忆问题,
这里推荐使用 Leanback 的 HorizontalGridView 作为标题栏使用,已经帮你处理焦点记忆问题,并且很不错.
标题栏
xml 大概如下 布局如下
<!-- 影视标题栏 --> <com.open.leanback.widget.HorizontalGridView android:id="@+id/" android:layout_width="match_parent" android:layout_height="@dimen/title_h" /> <!-- 影视内容 --> <android.support.v4.view.ViewPager android:id="@+id/*" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent"/>
HorizontalGridView 其实继承的 RecyclerView,使用方式是一样的.
mTitlerAdapter = new TitlerAdapter(); titleHgridview.setAdapter(mTitlerAdapter); // 进行强转,GridLayoutManager. ((GridLayoutManager)titleHgridview.getLayoutManager()).setOnChildSelectedListener(new OnChildSelectedListener() { @Override public void onChildSelected(ViewGroup parent, View view, int position, long id) { // 选中某个item的处理, 比如翻页等等操作 } });
这里给大家介绍一个小技巧 android:duplicateParentState=”” 的使用,再配合 selector,然后布局里面的 控件都可以获取到父布局的属性,爽歪歪.
ViewPager内容
- 布局里面使用 VerticalGridView,这里就相当使用 GridView,类似下图.
mMoviceAdapter = new MoviceAdapter(); moviceVgridview.setAdapter(mMoviceAdapter); // 初始化影视垂直布局. moviceVgridview.setNumColumns(6); // 因为标题下面布局的焦点上不去标题栏,需要设置,具体原理参考源码. ((GridLayoutManager)moviceVgridview.getLayoutManager()).setFocusOutAllowed(true, true); ((GridLayoutManager)moviceVgridview.getLayoutManager()).setOnChildSelectedListener(new OnChildSelectedListener() { @Override public void onChildSelected(ViewGroup parent, View view, int position, long id) { } }); // FocusOutAllowed focusOutSidAl... 也可以再xml设置,设置的属性如下,具体参考谷歌demo <declare-styleable name="lbBaseGridView"> <attr name="focusOutFront" format="boolean"/> <attr name="focusOutEnd" format="boolean"/> <attr name="focusOutSideStart" format="boolean"/> <attr name="focusOutSideEnd" format="boolean"/> <attr name="horizontalMargin" format="dimension"/> <attr name="verticalMargin" format="dimension"/> <attr name="android:gravity"/> </declare-styleable>
- 如果想实现复杂的带标题栏的布局,类似下面的,或者小米瀑布流的.
// 使用 Leanback下列的数据结构,设置的方式和 Recyclerview差不多,具体也可以参考 Leabanck 的谷歌demo. ItemBridgeAdapter mItemBridgeAdapter; mVerticalGridView.setAdapter(mItemBridgeAdapter); // 测试数据,demo. public ItemBridgeAdapter getMoviceItemDatas() { mItemBridgeAdapter = new ItemBridgeAdapter(); CardPresenter cardPresenter = new CardPresenter(); final NewPresenterSelector newPresenterSelector = new NewPresenterSelector(); ArrayObjectAdapter mRowsAdapter = new ArrayObjectAdapter(newPresenterSelector); // 填入Presenter选择器. for (int i = 0; i < 100; i++) { ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); MoviceItemData moviceItemData = mMoviceItemData.get(i); // 包含标题+内容列表的数据 String title = moviceItemData .getTitle(); HeaderItem settingHeader = new HeaderItem(i, title); // 标题头(比如 xxx榜单) List<SettingItem> items = moviceItemData.getItems(); // 内容列表.(影视内容) // 小技巧: 比如需要像图片中的频道一样,这里服务端返回的数据很多,换行了, // 可以进数据分段,一行8个填入,最后一行的,设置 ListRow(null, listRowAdapter2),那么标题栏就没有了. // ArrayObjectAdapter listRowAdapter2 = new ArrayObjectAdapter(cardPresenter); listRowAdapter2.addAll(0, items); ListRow listRow2 = new ListRow(settingHeader, listRowAdapter2); mRowsAdapter.add(listRow2); } mItemBridgeAdapter.setAdapter(mRowsAdapter); return mItemBridgeAdapter; }
PresenterSelector 选择器,具体可以参考谷歌demo.
public class NewPresenterSelector extends PresenterSelector { private AListRowPresenter mNewListRowPresenter = new AListRowPresenter(); private ARowPresenter mNewListRowPresenter2 = new AListRowPresenter(); public NewPresenterSelector() { } @Override public Presenter getPresenter(Object item) { // 根据item判断,加载相应的 presenter,这里主要为了显示不同的东西. } @Override public Presenter[] getPresenters() { return new Presenter[]{ * * }; } }
如何添加按键加载更多
由于TV上面属于遥控器操作,不像手机上面那样.
@Override public void onScrollStateChanged(int state) { if (state == SCROLL_STATE_IDLE) { if (getLastVisiblePosition() >= getAdapter().getItemCount() - 1) { // 加载更多 } } super.onScrollStateChanged(state); } public int getLastVisiblePosition() { final int childCount = getChildCount(); if (childCount == 0) return 0; else return getChildAdapterPosition(getChildAt(childCount - 1)); } // 也可以再这里进行处理,具体看需求了,还有个人喜好. @Override public boolean dispatchKeyEvent(KeyEvent event) { return super.dispatchKeyEvent(event); }
如何适配不同分辨率
我这里使用的是 AutoLayout,我以前也写过一篇文章 android tv如何适配不同平台,这里就不过多废话了.
放大效果
配合移动边框边框使用
多级菜单的编写
这里的菜单有2级,DEMO是一个直播的频道选择,显示预告信息的二级菜单.
键盘的编写
使用的 Leanback完成的 全键盘,T9键盘.
性能优化与安全等
有空后续整理到文章,笔记更新处:http://b53aa9d9.wiz03.com/share/s/2ReGDp2ND4ay2QH8h-1Hn0g13xil582J-Ahk2NIIwD0Z5Qt0
转载于:https://my.oschina.net/hailongqiu/blog/
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233888.html原文链接:https://javaforall.net