最近完成了一個(gè)TV端的項(xiàng)目,大致包括影視凌受、直播觀看阵子,手機(jī)投屏操控,內(nèi)容分類(lèi)推薦等功能胜蛉,解決了一些坑挠进,但同時(shí)也挖了好多(逃(●'?'●),在此簡(jiǎn)單記錄一下
1.foucus焦點(diǎn)問(wèn)題:
簡(jiǎn)單基礎(chǔ)的view通過(guò)android:focusable="true"
誊册、android:nextFocusLeft=""
领突、設(shè)置selector背景
等屬性就可以搞定,但如果你要實(shí)現(xiàn)復(fù)雜布局(或者嵌套布局)的recyclerview或者listview案怯,那就需要自己重寫(xiě)事件處理了君旦。當(dāng)然你和我一樣懶得話,可以使用google的leanback庫(kù)嘲碱,不過(guò)這樣可客制化的空間就變小了金砍,個(gè)人也不是很推薦使用吧,有利有弊麦锯,具體怎樣使用下面解釋恕稠。
2.播放器IjkPlayer問(wèn)題
主要就是so庫(kù)蛋疼的編譯問(wèn)題。扶欣。鹅巍。如果你是windows電腦的話基本可以不用自己編譯了千扶,可以在這做一回伸手黨拿到so庫(kù),接下來(lái)就是自己把IjkPlayer封裝成一個(gè)自定義的framelayout昆著,根據(jù)需求處理其各種回調(diào)(緩沖县貌、暫停术陶、啟動(dòng)凑懂、重播、后臺(tái)梧宫、出錯(cuò)接谨、完成等等),開(kāi)心的是TV端只要做一些最簡(jiǎn)單的播放操作就可以了塘匣,至于彈幕脓豪、旋轉(zhuǎn)、音量忌卤、亮度等完全不需要考慮扫夜。
播放結(jié)束后記得relase播放器即可。
3.手機(jī)投屏驰徊、操控問(wèn)題解決
采用了NSDManager+AsyncHttpServer開(kāi)源庫(kù)的方式起長(zhǎng)連接完成笤闯。簡(jiǎn)單解釋下就是:
---------------------Server(TV端)--------------------------------------------
1.后臺(tái)service起一個(gè)AsyncHttpServer
2.配置NsdServiceInfo的端口號(hào)、協(xié)議類(lèi)型棍厂、協(xié)議名等信息颗味,并注冊(cè)NSDManager Service (等待client 來(lái)掃描連接)
---------------------Client(手機(jī)端)---------------------------------------
3.注冊(cè)NsdManager.DiscoveryListener(掃描),及NsdManager.ResolveListener(掃描條件滿足后的連接listener)
4.連接socket
5.發(fā)送交互信息
連接完之后牺弹,我們就能自定義上層信息協(xié)議了(通過(guò)setStringCallback浦马,解析不同string完成不同操作)。比如說(shuō)用戶token傳遞张漂、投屏影片url傳遞晶默,完全只需要加密過(guò)后以string的方式傳遞過(guò)來(lái),server解析后跳轉(zhuǎn)對(duì)應(yīng)界面就行了航攒。至于遠(yuǎn)程遙控功能荤胁,目前我是使用Instrumentation來(lái)發(fā)送虛擬按鍵,從而完成手機(jī)遙控屎债。
4.界面展示與網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)
由于TV端一般都是采用tab標(biāo)簽+fragment的形式仅政,而且數(shù)據(jù)一般不會(huì)短時(shí)間內(nèi)變化,所以最好不要頻繁刷新數(shù)據(jù)與view盆驹,請(qǐng)求一次后如果沒(méi)有觸發(fā)刷新事件圆丹,你就可以一直用這次的response,fragment也只需要hide即可躯喇。
5.leanback相關(guān)使用問(wèn)題
主要是針對(duì)VerticalGridFragment的定制辫封,實(shí)現(xiàn)這樣一個(gè)界面硝枉,并可以將focus移動(dòng)到上方tab的位置。
官方demo也比較清楚倦微,要實(shí)現(xiàn)這樣一個(gè)效果妻味,只需要照著它的模板去實(shí)現(xiàn)一個(gè)PresenterSelector(如果只有一種viewtype,直接提供一個(gè)Presenter即可)和ArrayObjectAdapter即可欣福,將網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù)add進(jìn)adapter就會(huì)自動(dòng)去notify责球,主要是一些UI細(xì)節(jié)方面需要我們?nèi)ジ淖儭?/p>
- 加載數(shù)據(jù)前后loading界面:
getProgressBarManager().show();
getProgressBarManager().hide();
- 設(shè)置列數(shù),行間距:
/**
* 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頂層控件不能向上導(dǎo)航focus拓劝,如上圖中焦點(diǎn)無(wú)法移動(dòng)到我的收藏那一行item:
可以重寫(xiě)一個(gè)一模一樣的lb_vertical_grid_fragment雏逾,自己寫(xiě)的布局會(huì)覆蓋掉系統(tǒng)的布局,再將BrowseFrameLayout重寫(xiě)成我們自己的BrowseFrameLayout郑临。
主要是因?yàn)閂erticalGridFragment中的父布局?jǐn)r截了事件栖博,詳細(xì)原因可以看這