接下去應該是梳理一下 Android Tv 主界面實現(xiàn)原理及解析的一個系列博客了,大體上的安排是先介紹 Google 官方提供的 Leanback 庫的使用透硝,如何使用該庫來實現(xiàn)簡單的 Home 界面聪蘸,然后再去分析 Leanback 主界面實現(xiàn)的相關源碼宪肖,了解完 Google 是如何實現(xiàn)之后就可以扔掉 Leanback 自己來嘗試實現(xiàn),畢竟 Leanback 的可定制不高健爬。
效果圖
首先貼幾張常見的 Home 界面效果:
第一張是愛奇藝 Tv 應用的 Home 界面控乾,第二張是一個開源 Demo 的 Home 界面,第三張是 Google 官方 Tv Sample 的 Home 界面浑劳。
比較常見的 Home 界面風格應該是第一張和第二張的形式阱持,這兩種的 ui 實現(xiàn)也不一樣夭拌,因此我就想搞懂這兩種界面分別是如何實現(xiàn)的Dа衷咽!
目前重點研究第一張的實現(xiàn)方式吧,畢竟 Google 的 Leanback 庫實現(xiàn)出來的效果跟第一張有一些共同點蒜绽,因此可以從 Leanback 入手來學習它是如何實現(xiàn)的镶骗。而至于第二張的實現(xiàn)原理,目前還沒有思路躲雅,也暫時找不到相關資料來學習鼎姊,Github 上面的 demo 都是忽悠人,控件全都是在 xml 中直接寫死的相赁,所以第二張圖的 Home 界面實現(xiàn)原理以后再慢慢研究吧相寇,或者有讀者可以指點一二,非常感激钮科。
分析
先大概的來分析一下第一張愛奇藝 Home 界面的實現(xiàn):
這個是 Tab 標簽欄唤衫,選中不同的 Tab,內(nèi)容區(qū)會顯示不同的視頻列表绵脯,這里的實現(xiàn)應該是 TabLayout + Fragment 的形式佳励,或者 TabLayout + ViewPager,但 ViewPager 在 Tv 上使用好像會出很多坑。
這個是內(nèi)容區(qū)域即可左右滑動又可上下滑動的視頻列表區(qū)域蛆挫,主頁最復雜的實現(xiàn)應該就是這個地方了赃承。要我實現(xiàn)的話,思路就是 RecyclerView 嵌套 RecyclerView 來實現(xiàn)悴侵,先不談 RecyclerView 這種滑動的控件在 Tv 上會出問題瞧剖,嵌套這個坑就足夠你填的了。
在 Tv 上可免,可以用 HorizontalGridView 和 VerticalGridView 替代 RecyclerView 使用筒繁。但要實現(xiàn)左右單行滑動,上下整體滑動的效果巴元,我只能想到上下用 VerticalGridView 來實現(xiàn)毡咏,每一行是它 itemView,而每一行的實現(xiàn)則用 HorizontalGridView 來實現(xiàn)逮刨。也就是 1 個 VerticalGridView + 多個 HorizontalGridView 來實現(xiàn)呕缭。
但這樣的嵌套仍會有許多問題出現(xiàn),比如快速移動時的焦點丟失修己、性能問題恢总、每一行的 View 如何緩存、復用等睬愤。
有大佬清楚解決方案片仿,或者有其他實現(xiàn)思路的小伙伴們歡迎指點一下,實在沒有尤辱,那就只能自己慢慢去啃 Leanback 的相關源碼砂豌,然后再來梳理一下了厢岂。
使用
不出意外,接下去的空閑時間應該就是啃 Leanback Home 界面實現(xiàn)的相關源碼阳距,在此之前塔粒,先了解一下 Leanback 如何使用,哪些類是重點筐摘,后面分析時才方便入手卒茬。
以下是我覺得應該理解的類:
- BrowerFragment:用來展示可左右上下滑動的視頻列表界面
- ArrayObjectAdapter:作用類似于 List,可以用于裝每一行的數(shù)據(jù)咖熟,也可以用于裝一行里的每一個 item 數(shù)據(jù)
- ListRowPresenter:Leanback 庫中的 Presenter 作用都有些類似于 RecyclerView.Adapter
- ListRow:可以理解成一個 Mode圃酵,也就是把每一行抽象封裝成一個 ListRow
用法跟 RecyclerView 很像,就是可能單獨從命名上來理解會有些亂馍管。只要你自己嘗試去利用 Leanback 去實現(xiàn)個最簡單的 Home 界面辜昵,大體就能理解了。比如咽斧,要實現(xiàn)下面這個 Home 界面:
首先堪置,界面顯示的數(shù)據(jù)都存在 ArrayObjectAdapter 里面,在 RecyclerView 時我們是存在 ArrayList 里:
初始化 ArrayObjectAdapter 對象時需傳入一個 Presenter 進去张惹,這里跟 RecyclerView 的使用有些不同舀锨,在 RecyclerView 里,我們是將 List 對象傳給 Adapter宛逗,讓 Adapter 去將數(shù)據(jù)和 itemView 綁定坎匿。這里雖然反過來將 Adapter(Presenter) 傳入 List(ArrayObjectAdapter) 里,但其實作用也差不多雷激,也是將兩者關聯(lián)起來替蔬。只是多了一個步驟,通過一個橋梁類 ItemBridgeAdapter 來將 ArrayObjectAdapter 里的數(shù)據(jù)傳給 Presenter 屎暇。之后 Presenter 的工作就跟 RecyclerView.Adapter 一樣了承桥。
前面說了 Presenter 作用類似于 Adapter,它是個抽象類根悼,繼承它的之類需要實現(xiàn)三個方法:onCreateViewHolder()凶异、onBindViewHolder()、onUnbindViewHolder()
挤巡,同 RecyclerView.Adapter 一樣剩彬,在 onCreateViewHolder()
里面創(chuàng)建 itemView,然后在 onBindViewHolder()
里面將數(shù)據(jù)和 itemView 綁定矿卑,比如:
最后調(diào)用 BrowerFragment 的 setAdapter() 將總的 ArrayObjectAdapter 對象設置進去喉恋,就可以了。使用很簡單,如果你第一次接觸轻黑,然后直接來看這篇糊肤,也許看不懂,建議你去看看這篇博客苔悦,或者自己去看一下 Google 官方的 Tv demo,然后再回來看椎咧,相信你理解就會跟深刻了玖详。
思考
學會初步使用 Leanback 實現(xiàn)一個簡單的 Home 界面后,你會發(fā)現(xiàn)勤讽,我們只需要提供每一行的數(shù)據(jù)蟋座,以及每行自己 itemView 的布局和數(shù)據(jù)綁定方式即可。但這完全沒有涉及到 HorizontalGridView 和 VerticalGridView 脚牍,那么它內(nèi)部的實現(xiàn)原理又是什么呢向臀?
如果你運行了 Google 官方 Tv sample 或者自己利用 Leanback 實現(xiàn)了簡單的 Home 界面的話,你會發(fā)現(xiàn)诸狭,我們焦點在某個 item 上時券膀,這個 item 會放大,焦點離開又恢復正常驯遇,這個 Leacback 又是怎么實現(xiàn)的呢芹彬?
如果你運行了愛奇藝的 Tv 應用,你會發(fā)現(xiàn)叉庐,它焦點在移動到邊界時 item 會有抖動的效果舒帮,這又要如何實現(xiàn)呢?
本系列梳理博客大概就是要理清上面的問題陡叠,后兩個比較簡單玩郊,看了 Leanback 的源碼,已基本明白枉阵。所以難啃的點還是在于 Home 界面的 ui 實現(xiàn)原理译红,目前只能大體上明白每一行是一個 HorizontalGridView,上下滑動是由什么實現(xiàn)還沒啃透兴溜。下一篇等啃得差不多了临庇,再來梳理一下。
最近剛開通了公眾號昵慌,想激勵自己堅持寫作下去假夺,初期主要分享原創(chuàng)的Android或Android-Tv方面的小知識,感興趣的可以點一波關注斋攀,謝謝支持~~