你不能不知道的Flutter:Flutter影片滾動播放解決方案
如題,本文分享的內容為:影片列表滾動播放。
分類
影片列表的播放規則一般需要和具體產品、互動確認,播放一般都是靜音的,根據露出座標規律,常見的有兩大類:
固定位置播放
如滑動螢幕的中間位時,延遲若干毫秒自動播放。
固定索引+屏佔比播放
如第一個符合屏佔比的影片可以自動播放;屏佔比可以是當前影片元件的高度百分比,也可以是螢幕上的固定位置;當我們把屏佔比定位60%時,第一個影片的可見區小於60%會暫停播放,觸發可見的下一個影片。
有料影片流
在開發
安居客-有料
內容Feed流時,我們遇到的互動是第二種,由於影片貼出現不固定,待播放的位置也不固定。 在這種情況下要實現與Native一致的效果是一個不小的難題。
我們在開發過程中將這個問題進行了分解:
- 滾動檢測:拋開影片,單純設計一個元件,能夠按需檢測特定Widget
- 影片播放元件:引入影片播放,將影片控制元件根據滾動檢測要求,進行接入
元件原型
下面看一下我們設計的原型元件效果。
我們將影片貼子用一個色塊進行佔位。透過監聽滑動事件,當停止後,從螢幕頂端開始,遍歷當前視窗範圍內的控制元件,如果是影片控制元件,並且在螢幕上的露出比符合預期,那麼將其返回。供開發者後續處理。
核心流程如下圖所示:
基於這個思路,我們開發了一個
ScrollDetectListener
元件:
- 使用ScrollDetectListener包裹ListView,ListView為業務相關的影片流帖子。
- 影片帖子使用MetaConsumer包裹;
MetaConsumer( index: index, data: data, builder: (BuildContext context, VideoPlayModel model, Widget child) { var play = model.playIndex == index; return Container( width: MediaQuery.of(context).size.width, alignment: Alignment.center, height: 100, padding: EdgeInsets.zero, child: play ? Text('Playing $data') : Text('$data'), color: play ? Colors.redAccent : Colors.grey[100] ?? Colors.grey, ); })
影片檢測元件
透過原型完成必要的除錯和最佳化之後,我們可以嘗試接入影片控制元件。
Demo1
Demo2
在處理影片的時候,需要注意的點也很多,比如:
- 影片貼的首幀預覽圖/封面圖,採用影片首幀,會遇到影片開頭是黑屏的問題,採用獨立封面圖相對效果會更好。
- 影片高寬比控制
- 帖子狀態控制:待播放,載入中,播放,迴圈/靜音等
其他方案
除了我們的實現方案,目前還可以找到的一個開源庫: inview_notifier_list。
這個開源庫它支援固定位置播放,也就是我們說的以第一種型別。
該專案提供了預覽效果和demo,非常良心的作者。
Demo1
Demo2
他的基本原理如下:
- 設計了一個InViewState容器,繼承了ChangeNotify,用於記錄列表中的子Widget的context資訊,
InViewState state = InViewNotifierList.of(context);
- 當影片Widget執行build時,呼叫InViewState.addContext加入集合中
- 同時影片Widget本身需要用AnimatedBuilder將InViewState和影片狀態進行關聯,也就是當InViewState更新時,重新構建影片Widget
- 什麼時候更新InViewState呢?答案是滑動過程中。滑動的時候開始遍歷前面加入的影片Widget的contxt,其實就是為了透過context難道控制元件最終的座標,判斷是不是符合規則
- 如果座標位置命中規則,就會吧當前的控制元件的標識id快取到一個集合中
_currentInViewIds
,然後通知觀察者資料變化了,所以AnimatedBuilder會觸發child的build - 在child的build時(也就是前面提到的影片空間build),就會在判斷當前影片的id是否在
_currentInViewIds
中,進行差異化繪製。
我們用一張圖來概括性大致流程:
可以看到這裡面有兩個集合,分別用那個有快取控制元件的Context和名中控制元件資料。為了避免遍歷的效能問題,作者引入了快取閾值,可以由使用者根據實際情況調整快取context的個數。比如我們可以把個數設定為一個螢幕最多能展示的影片條數。這樣很可能不超過5個。
///Add the widget's context and an unique string id that needs to be notified.void addContext({@required BuildContext context, @required String id}) { _contexts.add(_WidgetData(context: context, id: id)); }///Keeps the number of widget's contexts the InViewNotifierList should stored/cached for///the calculations thats needed to be done to check if the widgets are inView or not.///Defaults to 10 and should be greater than 1\. This is done to reduce the number of calculations being performed.void removeContexts(int letRemain) { if (_contexts.length > letRemain) { _contexts = _contexts.skip(_contexts.length - letRemain).toSet(); } }
這個實現方案基本滿足的場景一的規則。並且實現了區域性重新整理的監聽。
下面我們看下場景二,如果要基於當前影片的位置做計算,這個庫支援不了。
可以看到它暴露的引數: 影片控制元件上邊緣差值,下邊緣差值值,視窗高度H
//Check if the item is in the viewport by evaluating the provided widget's isInViewPortCondition condition. isInViewport = _isInViewCondition(deltaTop, deltaBottom, vpHeight);
如果我們要計算影片控制元件自身的露出情況,需要單獨獲取控制元件的座標和大小來計算。如果進行二次開發,只需要將判定函式擴充套件一些引數即可。
小結
這兩種方案,在檢測影片貼的邏輯上分別採用了主動檢測和被動檢測; 最大差異是我們沒有將影片貼提前新增到集合中,所以不用維護一個固定容量的快取集合。
目前我們的影片滾動播放方案已經完成元件改造,很快將對外開源,敬請期待。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952849/viewspace-2671873/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Flutter(十) 音訊+影片播放Flutter音訊
- Flutter(十)之Flutter的滾動WidgetFlutter
- Flutter滾動動畫Flutter動畫
- 【Flutter】修改flutter_boost,相容iOS側滑的一個解決方案FlutteriOS
- 影片直播網站原始碼,flutter 頂部滾動欄頁面網站原始碼Flutter
- 【譯】定製Flutter滾動效果Flutter
- Flutter 頁面滾動吸頂詳解(NestedScrollView)FlutterView
- 使用 flutter 的ListView實現滾動列表FlutterView
- Flutter Web 跨域問題解決方案FlutterWeb跨域
- 移動端滾動穿透解決方案穿透
- 在Flutter中嵌入Native元件的解決方案Flutter元件
- Flutter - 不一樣的跨平臺解決方案Flutter
- 【Flutter實戰】自定義滾動條Flutter
- Flutter 滾動控制元件篇-->ListViewFlutter控制元件View
- Flutter可滾動Widgets-ListViewFlutterView
- Flutter 初探(四):滾動類WidgetsFlutter
- Flutter滾動型容器元件 - ListView篇Flutter元件View
- Flutter SingleChildScrollView 滾動頁面FlutterView
- RecyclerView 平滑滾動可控制滾動速度的終極解決方案View
- flutter packages get - pub get failed (1)解決方案FlutterPackageAI
- 一套Flutter混排瀑布流解決方案Flutter
- Flutter中http請求抓包解決方案FlutterHTTP
- 一種更優雅的Flutter Dialog解決方案Flutter
- 天吶!你竟然不知道Flutter中的"通知冒泡"Flutter
- Flutter 動態化方案探索Flutter
- Flutter 滾動監聽及實戰appBar滾動漸變FlutterAPP
- 遇到overflow: scroll不能平滑滾動怎麼解決?
- 移動端滾動穿透問題解決方案穿透
- Flutter+小程式容器: 1+1>2的解決方案Flutter
- 五個你所不知道的Flutter開發細節Flutter
- 【前端詞典】滾動穿透問題的解決方案前端穿透
- 移動端滾動穿透問題完美解決方案穿透
- Flutter 滾動控制元件篇-->滾動監聽及控制(ScrollController)Flutter控制元件Controller
- flutter好用的輪子推薦十五-flutter給滾動內容新增粘性header元件FlutterHeader元件
- 網頁看影片不能全屏怎麼辦_win10影片無法全屏播放的解決方法網頁Win10
- 多層 UIScrollView 巢狀滾動解決方案UIView巢狀
- 為你的 Flutter APP 新增互動性FlutterAPP
- Flutter 滾動元件內容更新時自動定位到底端的方法Flutter元件