Android列表視頻播放開發之路

來張簡單的效果圖:

scale.gif

代碼均在:ListVideoPlay

問題引出

半年前開始接觸Android列表播放短視頻開發是從 VideoPlayerManager 這里開始的。
該庫核心思路:

1.使用TextureView嵌套在Item View里面作為視頻渲染
2.將視頻的生命周期全部在子線程隊列執行,然后post到主線程,避免ANR以及周期混亂
對此在Medium上作者做出了解釋

但存在一個棘手的問題:

由于TextureView是在ItemView中,所有壓根就不能無痕全屏切換播放
但是對于國內的視頻播放app來說,敢問哪家不要求全屏播放?

于是想出了一個方案就是在ListView或者RecyclerView布局同等層級中加入視頻播放的布局,將播放布局依附在itemView的顯示區域,然后監聽ListViewRecyclerView的滾動,通過滾動的位置來動態移動視頻播放布局的位置,這樣在全屏只需要將出了ListViewRecyclerView外的其他布局全部隱藏,將視頻播放的播放Resize到屏幕的寬高。大致的代碼可以在ListViewFragment這里看到.

BTW:就我所看到的,敢打賭目前市面上大部分的所謂的列表播放視頻思路大致如此

上述雖然能實現功能,但是在維護上存在極大的問題,無論是ListViewRecyclerView各種詭異滾動問題以及ViewPager相關的滾動問題, 還是每次新建一個頁面都要將視頻所有的布局寫死在xml文件中。完全無任何擴展性可言。并且當需要在點擊視頻時進入詳情頁? 落地頁 ?做無痕,不斷播的交互簡直是天方夜譚。

既然思路沒問題,那就著手優化重構了。其實只要找到問題的關鍵點:

  1. 視頻布局真的就必須固定在某個頁面布局中?
    2.視頻布局每次滾動都會有一個可依附的View(粘在上面,看著就像內嵌在列表里面一樣),必須要監聽ListView,ViewPager的滾動?
    3.視頻布局無論是橫豎屏或者進入詳情頁的視頻布局應該都必須是同一個才能保證無痕播放
    橫豎屏保證是同一個尚好處理,但是當需要切換界面的時怎樣保證是同一個

解決方案

一個Activity擁有一個頂層的View 即:
(ViewGroup) mContext.getWindow().getDecorView()
該decorView能保證隨時隨地都能附在activity的最頂層,將視頻播放相關的所有布局都置于其中就能解決問題1和3 存在的問題

但當將布局Add到DecorView后,會導致任何時候視頻布局都會在頂層,會遮擋StatusBar,ActionBar或者其他滾動列表之外的布局,此時就需要將視頻的播放布局嵌套在一個FrameLayout 中,如 VideoLayerView.java#L47,當視頻整體的布局是在合理的范圍(指滾動列表在整個屏幕的繪制區域Rect) 滾動此FrameLayout , 當在非合理范圍內就滾動真正的視頻布局, 這樣就完美的將視頻播放的布局 Attach在了列表item上跟隨滾動了

Android在ViewTreeObserver中添加了每個View,改View的相關變化都會在ViewTreeObserver回調,比如說:

mTrackView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
                    @Override
                    public void onScrollChanged() {
                        //View滾動時會回調
                    }
                });

mTrackView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        //重新layout會被回調
                    }
                });

在此只需要關心ViewTreeObserver.OnScrollChangedListener即可,這樣就根本不用關心ListView,RecyclerView,ViewPager的滾動距離來改變視頻布局的位置了,具體代碼可在ViewTracker.java#L202 查看到

因此根據上述思路簡單設計出了 一個View 粘附到 另一個View上 且跟隨滾動的框架
詳情見 ViewTracker

放張效果圖:

bullheadN4F26Tbrucetoo04112017181910.gif

Demo DetailFragment

只要將跟隨滾動的邏輯處理ok,視頻播放相關的可以將播放布局參照demo來進行整合就能實現無縫播放

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容