Android Flutter實(shí)現(xiàn)彈幕效果
前言
需求要點(diǎn)如下:
- 彈幕行數(shù)為3行,每條彈幕相互依靠但不存在重疊
- 每條彈幕可交互點(diǎn)擊跳轉(zhuǎn)
- 滾動(dòng)速度恒定 觸摸不可暫停播放
- 彈幕數(shù)據(jù)固定一百條且支持輪詢播放
彈幕排序規(guī)則如下:
1 4 7
2 5 8
3 6 9
通用彈幕實(shí)現(xiàn)方案
Flutter Dev Package
已有開源彈幕實(shí)現(xiàn)組件,這里舉例barrage_page
的實(shí)現(xiàn)方式(大多數(shù)實(shí)現(xiàn)底層邏輯基本一樣)。
基本架構(gòu)采用Stack然后向布局中提交彈幕布局,添加時(shí)設(shè)置好彈幕偏移量來設(shè)置彈幕位置。
Stack(fit: StackFit.expand, children: <Widget>[ widget.child, _controller.isEnabled ? Stack( fit: StackFit.loose, children: <Widget>[] ..addAll(_widgets.values ?? const SizedBox())) : const SizedBox(), ]); });
但因?yàn)槊織l彈幕可能會(huì)出現(xiàn)重疊情況無法合理定位每條彈幕的位置因此放棄該方案。
PS:widget只有在build到布局后才能獲取到它基礎(chǔ)信息(相對位置信息,寬高等)就無法計(jì)算出所有彈幕的位置信息。
ListView彈幕方案實(shí)現(xiàn)
最先想到使用瀑布流flutter_staggered_grid_view
實(shí)現(xiàn)彈幕布局但由于組件暫時(shí)不支持橫向布局就放棄了。
基本框架
采用三個(gè)ListView實(shí)現(xiàn)每一行彈幕效果。雖然不太推薦以這種形式實(shí)現(xiàn)但從快速實(shí)現(xiàn)效果來說是比較簡單便捷兜底方案。(可以實(shí)現(xiàn)但不推薦)
Container( height: 200, child: Column( children: [ Expanded( child: ListView.builder( scrollDirection: Axis.horizontal, controller: scrollController1, itemBuilder: (context, index) { return Common.getWidget(index, height: 30, width: random.nextInt(100).toDouble()); }, ), ), Expanded( child: ListView.builder( scrollDirection: Axis.horizontal, controller: scrollController2, itemBuilder: (context, index) { return Common.getWidget(index, height: 30, width: random.nextInt(100).toDouble()); }, )), Expanded( child: ListView.builder( scrollDirection: Axis.horizontal, controller: scrollController3, itemBuilder: (context, index) { return Common.getWidget(index, height: 30, width: random.nextInt(100).toDouble()); }, )) ], ), )
輪播滾動(dòng)
添加定時(shí)器periodic
定時(shí)每秒鐘執(zhí)行一次scrollController
的animateTo
方法移動(dòng)偏移量并且偏移量不斷累加。
其次ListView
支持無限滑動(dòng)只要ListView.builder
不設(shè)置itemCount
就能實(shí)現(xiàn)。
Timer _timer; scroll = () { offset += 100; scrollController1.animateTo(offset, duration: Duration(seconds: 1), curve: Curves.linear); scrollController2.animateTo(offset, duration: Duration(seconds: 1), curve: Curves.linear); scrollController3.animateTo(offset, duration: Duration(seconds: 1), curve: Curves.linear); }; _timer = Timer.periodic(Duration(seconds: 1), (timer) { scroll(); });
輪詢算法
ListView
支持無限滑動(dòng)后itemBuilder
回調(diào)下標(biāo)Index
會(huì)超出數(shù)據(jù)源最大值。因此數(shù)據(jù)源也需要支持無限輪詢來配合列表滾動(dòng)。start
表示彈幕開始取值,這里設(shè)置為(0,1,2);index
表示itemBuilder
回調(diào)下標(biāo)Index
。
int findIndex(int start, int index) { index = start + index * 3; if (expressList.length < index) { index = index % (expressList.length - 1); // 取余 } else if (expressList.length == index) { // 是否是最后一個(gè)數(shù)據(jù) index = start; if (index >= expressList.length) { // 還需要判斷數(shù)據(jù)源是否比start還小 index = (index % expressList.length - 1); } } return index; }
點(diǎn)擊事件
一切都實(shí)現(xiàn)得很順利最終就是彈幕點(diǎn)擊實(shí)現(xiàn)。但實(shí)際上當(dāng)ListView
的scrollController
在執(zhí)行animateTo
時(shí)其實(shí)點(diǎn)擊操作是失效的,ListView
無法響應(yīng)點(diǎn)擊事件。只有當(dāng)animateTo
操作結(jié)束之后再執(zhí)行點(diǎn)擊才能執(zhí)行點(diǎn)擊。因此若要實(shí)現(xiàn)這個(gè)功能只能先將Timer
暫停再執(zhí)行一次點(diǎn)擊,再一次點(diǎn)擊不可能是用戶再去觸發(fā),這里只能采用模擬點(diǎn)擊形式實(shí)現(xiàn)。
PS:ListView
無法響應(yīng)點(diǎn)擊事件具體原因還待研究,個(gè)人猜測列表做動(dòng)畫時(shí)對外部觸摸事件進(jìn)行了屏蔽處理。
GestureDetector( onTapUp: (details){ // 點(diǎn)擊抬起之后暫停定時(shí)器 _timer?.cancel(); // 模擬一次點(diǎn)擊 Timer(Duration(milliseconds: 100),() { GestureBinding.instance.handlePointerEvent(PointerAddedEvent(pointer: 0,position: details.globalPosition)); GestureBinding.instance.handlePointerEvent(PointerDownEvent(pointer: 0,position: details.globalPosition)); GestureBinding.instance.handlePointerEvent(PointerUpEvent(pointer: 0,position: details.globalPosition)); }); }, child: ListView.builder( controller: scrollController, physics: NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return GestureDetector( behavior: HitTestBehavior.opaque, child: Common.getWidget(index), onTap: () { // 內(nèi)部響應(yīng)點(diǎn)擊事件 然后重新設(shè)置定時(shí)器滾動(dòng)列表 _timer = Timer.periodic(Duration(seconds: 1), (timer) { scroll(); }); }, ); }, ), );
到此這篇關(guān)于Android Flutter實(shí)現(xiàn)彈幕效果的文章就介紹到這了,更多相關(guān)Flutter彈幕效果內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android?Flutter繪制有趣的?loading加載動(dòng)畫
- Android Flutter利用CustomPaint繪制基本圖形詳解
- Android Flutter制作交錯(cuò)動(dòng)畫的示例代碼
- Android Flutter表格組件Table的使用詳解
- Android Flutter實(shí)現(xiàn)GIF動(dòng)畫效果的方法詳解
- Android利用Flutter實(shí)現(xiàn)立體旋轉(zhuǎn)效果
- Android?Flutter實(shí)現(xiàn)"斑馬紋"背景的示例代碼
- Android?Flutter實(shí)現(xiàn)有趣的頁面滾動(dòng)效果
- Android使用Flutter實(shí)現(xiàn)錄音插件
相關(guān)文章
Android進(jìn)階之從IO到NIO的模型機(jī)制演進(jìn)
這篇文章主要為大家介紹了Android進(jìn)階之從IO到NIO的模型機(jī)制演進(jìn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Android?側(cè)滑按鈕的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android?側(cè)滑按鈕的實(shí)現(xiàn),本文結(jié)合示例代碼圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04Android仿eleme點(diǎn)餐頁面二級(jí)聯(lián)動(dòng)列表
本站一直在點(diǎn)外賣,于是心血來潮就像仿餓了么做個(gè)站,接下來通過本文給大家介紹android 二級(jí)聯(lián)動(dòng)列表,仿eleme點(diǎn)餐頁面的相關(guān)資料,需要的朋友可以參考下2016-10-10Android項(xiàng)目中使用HTTPS配置的步驟詳解
這篇文章主要給大家介紹了關(guān)于Android項(xiàng)目中使用HTTPS配置步驟的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-06-06Flutter?DateTime日期轉(zhuǎn)換的詳細(xì)使用
本文主要介紹了Flutter?DateTime日期轉(zhuǎn)換的詳細(xì)使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05Android微信自動(dòng)搶紅包插件優(yōu)化和實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Android微信自動(dòng)搶紅包插件優(yōu)化和實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12Android PickerView實(shí)現(xiàn)三級(jí)聯(lián)動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Android PickerView實(shí)現(xiàn)三級(jí)聯(lián)動(dòng)效果,PickerView實(shí)現(xiàn)全國地址的選擇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01Android數(shù)據(jù)存儲(chǔ)幾種方式講解
在開發(fā)過程中,數(shù)據(jù)存取是較為頻繁的,今天我們來了解下android幾種常見的數(shù)據(jù)存取方式。在Android中,sharePreferences是一種輕量級(jí)的數(shù)據(jù)存儲(chǔ)方式,采用鍵值對的存儲(chǔ)方式,存儲(chǔ)少量數(shù)據(jù),支持基本類型的簡單數(shù)據(jù)存儲(chǔ)2022-12-12android9.0 默認(rèn)apk權(quán)限添加方法
本文給大家分享android9.0 默認(rèn)apk權(quán)限添加方法,默認(rèn)賦予全部權(quán)限,根據(jù)包名賦予權(quán)限,通過default-permissions-google.xml的方式實(shí)現(xiàn),文中通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-06-06