欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android?Flutter控件封裝之視頻進(jìn)度條的實現(xiàn)

 更新時間:2023年06月27日 09:30:04   作者:二流小碼農(nóng)  
這篇文章主要來和大家分享一個很簡單的控制器封裝案例,包含了基本的播放暫停,全屏和退出全屏,文中的示例代碼講解詳細(xì),感興趣的可以了解一下

視頻控制器,三方所提供的樣式,有時很難滿足我們的需求,對于此情況,我們不得不在此基礎(chǔ)上自行封裝,今天所分享的文章就是一個很簡單的控制器封裝案例,包含了基本的播放暫停,全屏和退出全屏,以及時間和進(jìn)度的展示,封裝了事件回調(diào)以及各個屬性的控制,基本上可以滿足大部分的業(yè)務(wù)需求,即便不滿足,大家也可以在此基礎(chǔ)之上拓展。

我們還是按照慣例,簡單羅列一個大綱:

1、基本的效果展示

2、具體使用和相關(guān)屬性介紹

3、控制器封裝考慮因素

4、控制器部分功能代碼刨析

5、總結(jié)及源碼地址

一、基本的效果展示

具體的效果,沒什么好說的,都是大眾常見的樣式,依次從左到右為:播放暫停按鈕,播放時間,播放進(jìn)度,總的時間,全屏及退出全屏按鈕。

可以實現(xiàn)的功能有,圖標(biāo)的動態(tài)設(shè)置,時間進(jìn)度的顏色及大小控制,以及定時器的開啟,具體的可以看第二項。

二、具體使用和相關(guān)屬性介紹

1、具體使用

作為一個Widget,大家可以隨意使用,單獨亦或者和視頻播放器綁定使用。

VipVideoController(
        totalTime: 1000 * 60,
        backgroundColor: Colors.red,
        progressColor: Colors.amber,
        thumbColor: Colors.red,
        textStyle: TextStyle(color: Colors.red),
        onVideoPlayClick: (isPlay) {
          print("當(dāng)前播放按鈕狀態(tài)$isPlay");
        },
        onVideoFullScreenClick: (isFullScreen) {
          print("當(dāng)前全屏按鈕狀態(tài)$isFullScreen");
        },
        onVideoChanged: (position) {
          //返回毫秒
          print("當(dāng)前拖拽的進(jìn)度$position");
        }
      )

2、相關(guān)屬性

屬性類型概述
heightdouble設(shè)置控制器高度
progressHeightdouble進(jìn)度條高度
videoPlayIconString視頻播放Icon
videoPauseIconString視頻暫停Icon
videoFullScreenIconString視頻全屏Icon
videoExitFullScreenIconString退出全屏Icon
textStyleTextStyle文本樣式
backgroundColorColor背景顏色
progressColorColor進(jìn)度顏色
thumbColorColor拖動顏色
thumbRadiusdoublethumb大小
playTimeMarginLeftdouble播放時間距離左邊的距離
playTimeMarginRightdouble播放時間距離右邊的距離
videoTimeMarginLeftdouble視頻時間距離左邊的距離
videoTimeMarginRightdouble視頻時間距離右邊的距離
totalTimeint總時長
changeTimeint改變時長
isTimerbool是否需要定時
onVideoPlayClickValueChanged<bool>視頻播放點擊
onVideoFullScreenClickValueChanged<bool>視頻全屏點擊點擊
onVideoChangedValueChanged<int>滑動回調(diào)
onVideoChangeStartValueChanged<int>拖動開始
onVideoChangeEndValueChanged<int>拖動結(jié)束
isPlayedbool播放控制狀態(tài),暫停還是開始
isFullScreenbool是否是全屏

三、控制器封裝考慮因素

視頻控制器雖然說簡單,但需要考慮的因素還是比較多的,比如點擊播放和暫停,全屏和退出全屏的事件回調(diào),拖動進(jìn)度除了更改自身進(jìn)度也要更改時間進(jìn)度,傳遞的時間換算,定時的開啟和關(guān)閉等等都是需要解決的。

1、基本的UI設(shè)定

控制器的UI一定是基于設(shè)計同學(xué)所定的UI稿,否則就要以技術(shù)驅(qū)動設(shè)計更改,一般很難,不過也有特殊的案例存在。所以在封裝的時候,要么基于UI稿,要么就是動態(tài)可配置,通過屬性更改基本的樣式或者位置。

2、拖動進(jìn)度的實現(xiàn)

拖動進(jìn)度就比較簡單了,使用的是原生提供的Slider,也就是滑桿,類似于Android中的SeekBar,需要注意的是,顏色等屬性的動態(tài)配置。

3、時間的換算和進(jìn)度的綁定

時間的換算,需要把傳入的時間戳,轉(zhuǎn)化為我們所需要的時間格式,也就是時分秒的格式,這里使用了intl國際化的插件,主要用到到格式轉(zhuǎn)換DateFormat。

4、定時器的控制

定時器很簡單,實例化一個Timer即可,但是,什么時候開始,什么時候暫停都是我們需要考慮的,一般情況下,直接和視頻播放器進(jìn)行綁定,直接更改進(jìn)度即可,就不用這個定時,如果要用,可以用一個屬性控制;在需要定時的情況下,點擊暫停,需要暫停定時,除此之外播放完畢后也需要暫停定時;當(dāng)拖動完畢后,需要開啟定時,點擊播放,也需要開啟定時,所以,對于定時器控制這一塊,一定要縷清楚。

四、控制器部分功能代碼刨析

1、基本的布局

很簡單,一個橫向的組件Row,包裹了5個子組件,進(jìn)度條使用Expanded,用于占有剩余的空間。

 return SizedBox(
        height: widget.height,
        child: Row(
          children: [
            getPlayIcon(), //開始和暫停
            getPlayTime(timeStampToStringDate(_progress)), //時間
            Expanded(child: getSliderTheme()), //進(jìn)度
            getVideoTime(timeStampToStringDate(widget.totalTime!)), //時間
            getFullScreenIcon() //全屏
          ],
        ));

播放Icon和全屏Icon

未傳Icon情況下,直接使用默認(rèn)的Icon,如果傳遞了,那么直接使用傳遞的,需要根據(jù)播放狀態(tài)展示播放按鈕還是暫停按鈕,全屏Icon需要根據(jù)是否全屏狀態(tài),來展示對應(yīng)的圖標(biāo),同時回調(diào)點擊事件,VipImage是之前封裝的圖片組件,大家可以查看以往的分享。

  /*
  * 獲取播放Icon
  * */
  Widget getPlayIcon() {
    if (widget.videoPlayIcon == null) {
      return InkWell(
        onTap: onPlayClick,
        child: Icon(_isPlayed ? Icons.pause : Icons.play_arrow),
      );
    } else {
      return VipImage(
        _isPlayed ? widget.videoPlayIcon : widget.videoPauseIcon,
        onClick: onPlayClick,
      );
    }
  }
/*
  * 獲取全屏Icon
  * */
  Widget getFullScreenIcon() {
    if (widget.videoFullScreenIcon == null) {
      return InkWell(
        onTap: onFullScreenClick,
        child: Icon(_isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen),
      );
    } else {
      return VipImage(
        _isFullScreen
            ? widget.videoFullScreenIcon
            : widget.videoExitFullScreenIcon,
        onClick: onFullScreenClick,
      );
    }
  }

播放時長和總時長

VipText是之前封裝的文本組件,大家可以查看以往的分享,需要注意的是傳入的時間需要格式化處理,轉(zhuǎn)化為對應(yīng)的時分秒結(jié)構(gòu)。

  /*
   *獲取播放時長
   * */
  Widget getPlayTime(String text) {
    return VipText(
      text,
      style: widget.textStyle,
      marginLeft: widget.playTimeMarginLeft,
      marginRight: widget.playTimeMarginRight,
    );
  }
 /*
   *獲取總的播放時長
   * */
  Widget getVideoTime(String text) {
    return VipText(
      text,
      style: widget.textStyle,
      marginLeft: widget.videoTimeMarginLeft,
      marginRight: widget.videoTimeMarginRight,
    );
  }

中間的進(jìn)度條

進(jìn)度條使用的是Slider,直接按照原生的Api使用即可,需要注意,最大的進(jìn)度也就是max,需要和設(shè)置的總時長綁定,還有divisions分段,需要以秒作為區(qū)分,否則在滑動改變的時候,有可能會和定時造成沖突。

Widget getSliderTheme() {
    var divisions = widget.totalTime! / 1000;
    return SliderTheme(
      data: SliderThemeData(
          //高度
          trackHeight: widget.progressHeight,
          //去掉長按光暈
          overlayColor: Colors.transparent,
          //背景顏色
          inactiveTrackColor: widget.backgroundColor,
          activeTrackColor: widget.progressColor,
          thumbColor: widget.thumbColor,
          thumbShape:
              RoundSliderThumbShape(enabledThumbRadius: widget.thumbRadius)),
      child: Slider(
        min: 0,
        max: widget.totalTime!.toDouble(),
        value: _progress.toDouble(),
        divisions: divisions.toInt(),
        onChangeStart: (progress) {
          if (widget.onVideoChangeStart != null) {
            widget.onVideoChangeStart!(progress.toInt());
          }
        },
        onChangeEnd: (progress) {
          if (widget.onVideoChangeEnd != null) {
            widget.onVideoChangeEnd!(progress.toInt());
          }
          if (_isPlayed) {
            //播放狀態(tài)下,如果定時,才會執(zhí)行
            _startTimer();
          }
        },
        onChanged: (double value) {
          setState(() {
            _progress = value.toInt();
          });
          //回調(diào)當(dāng)前進(jìn)度
          if (widget.onVideoChanged != null) {
            widget.onVideoChanged!(_progress);
          }
        },
      ),
    );
  }

2、時間轉(zhuǎn)換

前邊有說過使用的是intl國際化插件,主要用到的是dateFormat.format()。

  /*
  * 時間戳轉(zhuǎn)換時間
  * */
  String timeStampToStringDate(int time) {
    String format = time < 1000 * 60 * 60 ? TimeUtil.m_s : TimeUtil.h_m_s;
    return TimeUtil.getTimeStampToStringDate(time, format: format);
  }
  /*
  * 時間戳轉(zhuǎn)時間
  * */
  static String getTimeStampToStringDate(int timeStamp,
      {String format = y_M_d}) {
    var dateFormat = DateFormat(format);
    var dateTime = DateTime.fromMillisecondsSinceEpoch(timeStamp);
    return dateFormat.format(dateTime);
  }

3、定時操作

定時需要注意的是,在需要定時的時候再開啟,比如定義的屬性為true時,就執(zhí)行開啟動作,當(dāng)開啟定時后,我們的進(jìn)度大于總時長時,就需要暫停定時。

開啟定時場景:1、定義的屬性為true時,進(jìn)入直接開啟定時。2、當(dāng)點擊開始播放按鈕時,如果使用定時,就要開啟,3、當(dāng)播放完畢后,再次拖動,也需要開啟定時。

暫停定時場景:1、點擊暫停視頻時,關(guān)閉定時,2、播放結(jié)束時,關(guān)閉定時,3、頁面銷毀時,也需要關(guān)閉定時。

/*
  * 開啟定時
  * */
  void _startTimer() {
    if (widget.isTimer! && _timer == null) {
      //開啟定時,一秒執(zhí)行一次
      _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
        if (_progress >= widget.totalTime!) {
          _pauseTimer();
        } else {
          setState(() {
            _progress += 1000;
          });
          widget.onVideoChanged!(_progress);
        }
      });
    }
  }
  /*
  * 暫停定時
  * */
  void _pauseTimer() {
    if (_timer != null) {
      _timer!.cancel(); //取消計時器
      _timer = null;
    }
  }

五、總結(jié)及源碼地址

源碼是一個簡單的文件,地址:github.com/AbnerMing888/flutter_widget/blob/master/lib/ui/widget/vip_video_controller.dart

源碼中有用到之前封裝的組件,請大家悉知,目前所封裝的組件,樣式和圖標(biāo)都是可以更換的,但是有一個就是位置還有組件是否顯示沒有封裝,不過源碼已經(jīng)貼出,大家可以在源碼基礎(chǔ)之上進(jìn)行更改。

以上就是Android Flutter控件封裝之視頻進(jìn)度條的實現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Android Flutter視頻進(jìn)度條的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論