Android TV

yifanwu發表於2021-09-09

前段時間突然接到任務要開發一個TV應用,整個過程還算順利,中間也有很多小插曲,其中最主要的一點關於TV開發方面的資料實在太少,找了不少資料但坑也不少,最近趁著有空,就將其中的一些坑整理一下

框架選擇

其實,TV框架要做的事情並不是很多,主要是解決如下幾個問題:

1,第一首要解決列表游標記憶問題,導致這個問題的主要原因是TV一般主要靠Focus 或者select 事件標識選中的位置,而在快速滑動時,當下一個view還沒生成時,將會導致滑不動。

2,重新整理列表時,view重繪,游標如何重新回到記憶位置

3, 在遙控器狀態下,點選列表重新整理某列資料,崩潰,這個在最後給出瞭解決方案

4,viewPager+Fragment  往邊緣位置移動,控制不划向下一頁

5,飛框動畫

6,選中發光背景**

儘量在開發前想好怎麼解決這些問題,免得事後來回重寫。

RecyclerView游標記憶,網上的解決方案很多,普通的列表,網格佈局都沒問題,當用到複雜佈局,快速移動時,大部分解決方案都是然並卵,TV開發優先是推薦使用官方的 LeanBack, 能解決大部分這些問題,但是因為Leanback 很多功能沒有完全開放

推薦使用  
基本能解決以上列表游標問題,包括下拉重新整理,這個庫本身是從LeanBack 改過來的,雖然其他很多解決方案中也提供了怎麼下拉重新整理,但是我使用過程當中,遇到了各種坑。

複雜佈局解決方案

例如一行row欄若干cloums,像上面說的大部分解決方案都失效了,我的佈局結構是 ViewPager +Fragment+Recyclerview,類似這種我使用的是  
其實在V14LeanBack也能解決,採用oneRow +more ListRow 不過感覺效能上會打些折扣

飛框動畫

試下這個吧
其實我用的是TV_Weight 但奈何也有點坑 ,而且有很多其他不需要的東西,預計後期會在專案中替換。個人覺得,如果有坑,能不用盡量不用

選中展示發光背景

例如我們是這樣的


圖片描述

image.png

瞭解 clipToPadding clipChildren

TV上大部分會採用放大某一項的方式標識選中位置,在使用的時候中需要加入這兩個屬性。

加了上面屬性後,比較複雜一點的問題如下,導致列表會滾動到上面,這裡只要在外面佈局去掉clipChildren 列表使用 padding,另外控制好列表寬度就好

圖片描述

image.png



當時我們使用的是tv_weight但是奈何這個庫在我使用的使用偶爾位置不是那麼準,並且只有外陰影,後面我們直接採用改背景的笨方法。當然也可以selector和和外陰影結合使用

除錯工具

前期用的是官方的模擬器,看不出飛焦等問題,用了  ,當然其他的也可以試試。能在盒子或者真機上開發最好

螢幕尺寸適配

螢幕尺寸適配方面使用的是dimens 檔案適配,當時查閱的是兩年以前的資料,適配性上就我在幾個模擬器和小米TV測試下來比純粹的dip相容性好很多,當時還查到一篇文章解釋了原理

但是dimens也有一些問題 如果適配的機型沒有包含在dimens 中也會導致佈局變形

事後,看一些資料也有推薦 鴻洋大神的 autoLayout的,結果大神又推薦了 presentLayout ,這個類庫已經廢棄推薦了官方的 ContrainLayout .

總結來說,autoLayout 的 issue還是不少的,好多還沒關閉,我自己採取的是ContrainLayout 和 dimens 配合使用 ,其實主要用到的是 ContrainLayout 百分比定位和百分比大小,一些不需要那麼精確的地方就使用了 dimens ,懶得算,其實按道理都用ContranLayout是最好的

約束佈局的百分比定位和大小,以前還不知道,專案做到後期,才使用上

文字適配

文字大小使用的是px,用sp的話 螢幕物理尺寸差別太大,到實際展示的效果還有是有段距離,總之用dimens 適配的 px ,起碼我測試的幾個機型下來沒啥大問題

以上用在普通手機適配按理也是可行的

關於ViewPager 配合Tab

預設情況下,往上移動時最靠近哪個tab就會移到哪個tab,建議在recyclerview的 dispatchKeyEvent 做個鉤子監聽keyup事件,如果移動到頂部,記憶tab requestFocus就好

        recyclerview.setOnKeyInterceptListener(new BaseGridView.OnKeyInterceptListener() {            @Override
            public boolean onInterceptKeyEvent(KeyEvent event) {                if (event.getAction() == KeyEvent.ACTION_DOWN) {                    switch (event.getKeyCode()) {                        case KeyEvent.KEYCODE_DPAD_LEFT:                            if (recyclerview.isFocusOnLeftmostColumn()) {                                if (oldView == null) {
                                    tbLayout.getChildAt(0).requestFocus();
                                } else {
                                    oldView.requestFocus();
                                }                                return true;
                            }                            return false;                        case KeyEvent.KEYCODE_DPAD_UP:                            return false;                        case KeyEvent.KEYCODE_DPAD_RIGHT:                            return false;                        case KeyEvent.KEYCODE_DPAD_DOWN:                            return false;                        default:                            return false;
                    }

                }                return false;
            }
        });

監聽KeyListener

監聽KeyListener時,有個問題,會呼叫兩次,後面發現是因為 ACTION_UP 和ACTION_UP都走事件,過濾掉其中一種就好

        recyclerview.setOnKeyInterceptListener(new BaseGridView.OnKeyInterceptListener() {            @Override
            public boolean onInterceptKeyEvent(KeyEvent event) {                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                 

                }                return false;
            }
        });

關於RecyclerView 重新整理某一項更新崩潰

在TV上透過遙控器或者鍵盤點選重新整理某一項,必現崩潰,不知道別人遇到沒有,呼叫這個方法就好了

  mRecycleViewAdapter.notifyItemChanged(position, "ivluowei");



作者:歲月留痕
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2157/viewspace-2816805/,如需轉載,請註明出處,否則將追究法律責任。

相關文章