Flutter 仿抖音效果 (三) 視頻播放列表

3.gif

Flutter 仿抖音效果 (一) 全屏點(diǎn)愛星
Flutter 仿抖音效果 (二) 界面布局

項(xiàng)目地址:https://github.com/CZXBigBrother/flutter_TikTok 持續(xù)效果更新

實(shí)現(xiàn)抖音視頻播放列表需要解決的問(wèn)題

  • 1.視頻播放
  • 2.切換時(shí)開始和停止視頻的播放

視頻播放

視頻播放實(shí)際實(shí)現(xiàn)是非常簡(jiǎn)單的只用使用VideoPlayerController就能快速的接入

video_player: ^0.10.1+5

使用到的API

  /// finished.
  Future<void> play() async {
  /// Sets whether or not the video should loop after playing once. See also
  /// [VideoPlayerValue.isLooping].
  Future<void> setLooping(bool looping) async 
  /// Pauses the video.
  Future<void> pause() async 
Snip20200113_2.png

加載完成前,使用第一幀的圖片作為預(yù)留圖,加載完成之后,隱藏預(yù)覽圖,保證短視頻加載緩慢是不會(huì)出現(xiàn)黑屏的情況 ,播放按鍵和預(yù)留圖都通過(guò)stack布局的方式進(jìn)行.

return Stack(
      children: <Widget>[
        GestureDetector(
            child: Stack(
              children: <Widget>[
                Container(
                  margin: EdgeInsets.only(top: ScreenService.topSafeHeight),
                  width: ScreenService.width,
                  height: h, //h/w = sh/sw
                  child: VideoPlayer(_controller),
                ),
                getPauseView()
              ],
            ),
            onTap: () {
              if (_controller.value.isPlaying) {
                _controller.pause();
                _hideActionButton = false;
              } else {
                _controller.play();
                videoPrepared = true;
                _hideActionButton = true;
              }
              setState(() {});
            }),
        // this.getVideo(),
        getPreviewImg(),
        getLikesView(),
        this.getUserAndTitle()
      ],
    );

上下切換列表

使用Swiper

 body: Container(
        child: Swiper(
          autoStart: false,
          circular: false,
          direction: Axis.vertical,
          children: children,
          controller: _controller,
        ),
        color: Colors.black,
      ),

切換時(shí)開始和停止視頻的播放

添加 SwiperController監(jiān)聽

  SwiperController _controller = SwiperController();

初始化時(shí) 我們會(huì)使用

會(huì)標(biāo)記 一個(gè)tag值用來(lái)判斷當(dāng)前隊(duì)列的編號(hào)

然后在當(dāng)滑動(dòng)到某個(gè)視頻時(shí)通知開始播放

    _controller.addListener(() {
      if (_controller.page.floor() == _controller.page) {
        eventBus.emit(keyPlayVideo + _controller.page.floor().toString(),
            _controller.page.floor());
      }
    });

這里會(huì)用到一個(gè)東西就是eventBus.這個(gè)和iOS 的KVO 差不多的意思.添加監(jiān)聽的KEY 然后注冊(cè)接受.內(nèi)部存儲(chǔ)里一個(gè)事件的隊(duì)列.發(fā)送通知是會(huì)執(zhí)行所有的接受者
在視頻controller中注冊(cè)監(jiān)聽eventBus

    eventBus.on(keyPlayVideo + widget.positionTag.toString(), (arg) {
      if (arg == widget.positionTag) {
        _controller.play();
        videoPrepared = true;
        _hideActionButton = true;
      } else {
        _controller.pause();
        _hideActionButton = false;
      }
      setState(() {});
    });

在dispose的時(shí)候必須移除eventBus 和 等等的Controller,否則會(huì)報(bào)錯(cuò)

  @override
  void dispose() {
    this.scroController.dispose();
    this.timer.cancel();
    _controller.dispose(); //釋放播放器資源

    super.dispose();
  }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容