【Android】TV端项目开发挖坑总结
最近完成了一个TV端的项目,大致包括影视、直播观看,手机投屏操控,内容分类推荐等功能,解决了一些坑,但同时也挖了好多(逃(●'◡'●),在此简单记录一下
1.foucus焦点问题:
简单基础的view通过android:focusable="true"
、android:nextFocusLeft=""
、设置selector背景
等属性就可以搞定,但如果你要实现复杂布局(或者嵌套布局)的recyclerview或者listview,那就需要自己重写事件处理了。当然你和我一样懒得话,可以使用google的leanback库,不过这样可客制化的空间就变小了,个人也不是很推荐使用吧,有利有弊,具体怎样使用下面解释。
2.播放器IjkPlayer问题
主要就是so库蛋疼的编译问题。。。如果你是windows电脑的话基本可以不用自己编译了,可以在这做一回伸手党拿到so库,接下来就是自己把IjkPlayer封装成一个自定义的framelayout,根据需求处理其各种回调(缓冲、暂停、启动、重播、后台、出错、完成等等),开心的是TV端只要做一些最简单的播放操作就可以了,至于弹幕、旋转、音量、亮度等完全不需要考虑。
播放结束后记得relase播放器即可。
3.手机投屏、操控问题解决
采用了NSDManager+AsyncHttpServer开源库的方式起长连接完成。简单解释下就是:
---------------------Server(TV端)--------------------------------------------
1.后台service起一个AsyncHttpServer
2.配置NsdServiceInfo的端口号、协议类型、协议名等信息,并注册NSDManager Service (等待client 来扫描连接)
---------------------Client(手机端)---------------------------------------
3.注册NsdManager.DiscoveryListener(扫描),及NsdManager.ResolveListener(扫描条件满足后的连接listener)
4.连接socket
5.发送交互信息
连接完之后,我们就能自定义上层信息协议了(通过setStringCallback,解析不同string完成不同操作)。比如说用户token传递、投屏影片url传递,完全只需要加密过后以string的方式传递过来,server解析后跳转对应界面就行了。至于远程遥控功能,目前我是使用Instrumentation来发送虚拟按键,从而完成手机遥控。
4.界面展示与网络请求数据
由于TV端一般都是采用tab标签+fragment的形式,而且数据一般不会短时间内变化,所以最好不要频繁刷新数据与view,请求一次后如果没有触发刷新事件,你就可以一直用这次的response,fragment也只需要hide即可。
5.leanback相关使用问题
主要是针对VerticalGridFragment的定制,实现这样一个界面,并可以将focus移动到上方tab的位置。
我的收藏.png官方demo也比较清楚,要实现这样一个效果,只需要照着它的模板去实现一个PresenterSelector(如果只有一种viewtype,直接提供一个Presenter即可)和ArrayObjectAdapter即可,将网络请求的数据add进adapter就会自动去notify,主要是一些UI细节方面需要我们去改变。
- 加载数据前后loading界面:
getProgressBarManager().show();
getProgressBarManager().hide();
- 设置列数,行间距:
/**
* Created by lucky on 2017/7/17.
*/
public class CustomVerticalGridPresenter extends VerticalGridPresenter {
private VerticalGridView gridView;
public CustomVerticalGridPresenter(int focusZoomFactor) {
super(focusZoomFactor);
}
@Override
protected void initializeGridViewHolder(ViewHolder vh) {
super.initializeGridViewHolder(vh);
gridView= vh.getGridView();
int top= DensityUtil.dip2px(vh.getGridView().getContext(),25);//this is the new value for top padding
int bottom= gridView.getPaddingBottom();
int right= gridView.getPaddingRight();
int left= gridView.getPaddingLeft();
gridView.setPadding(left+top,top,right+top,bottom+top);
gridView.setHorizontalSpacing(top);
gridView.setVerticalSpacing(top);
}
}
接着在VerticalGridFragment中:
CustomVerticalGridPresenter gridPresenter = new
CustomVerticalGridPresenter(ZOOM_FACTOR);
gridPresenter.setNumberOfColumns(COLUMNS);
setGridPresenter(gridPresenter);
- VerticalGridFragment顶层控件不能向上导航focus,如上图中焦点无法移动到我的收藏那一行item:
可以重写一个一模一样的lb_vertical_grid_fragment,自己写的布局会覆盖掉系统的布局,再将BrowseFrameLayout重写成我们自己的BrowseFrameLayout。
主要是因为VerticalGridFragment中的父布局拦截了事件,详细原因可以看这