Flutter通过Visibility来实现视频和图片的轮流切换

文章简介

本文章主要介绍使用Visibility组件来控制视频和图片的轮流切换。其实思路很简单:就是当视频播放完成之后判断下一个资源是图片还是视频,
如果是图片则启动一个定时器,定时器5秒之后通过iShowImg标记位控制图片的显示或者隐藏;
如果是视频则播放视频,并取消定时器;
重复执行以上步骤;

代码如下

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

 import 'dart:async';

import 'package:flutter/material.dart';

import 'package:video_player/video_player.dart';

///视频和图片轮播组件
///
class VideoImageShufflingWidget extends StatefulWidget {
  const VideoImageShufflingWidget({Key? key}) : super(key: key);

  @override
  _VideoImageShufflingWidgetState createState() =>
      _VideoImageShufflingWidgetState();
}

class _VideoImageShufflingWidgetState extends State<VideoImageShufflingWidget> {
  late VideoPlayerController _controller;


  //视频或者资源,读者需要更换自己项目中的图片或者视频资源
  List<String> imageList = [
    'assets/bg_weather.png',
    'http://192.168.31.36/ims/resource/17d87da3-4021-48b8-9c68-0d53d0c349df.mp4',
    "assets/flutter_icon.png",
    'assets/android_logo_256.png'
  ];
  //当前展示的图片地址
  String currentUrl ='';

  ///播放视频
  void playVideo1() async {
    if (_timer != null && _timer!.isActive) {
      _timer?.cancel();
    }
    _controller = VideoPlayerController.network(currentUrl);
    bool isFirst = false;
    _controller.initialize().then((value) {
      _controller.addListener(() async {
        Duration? res = await _controller.position;
        setState(() {
          if (res! >= _controller.value.duration) {
            if (!isFirst) {
              isFirst = true;
              currentIndex++;
              _controller.removeListener(() { });
              _controller.dispose();
              // printLogByFlag(true, 'currentIndex:${currentIndex}');
              // printLogByFlag(true, 'currentIndex % imageList.length:${currentIndex % imageList.length}');
              currentUrl = imageList[currentIndex % imageList.length];
              if (currentUrl.endsWith('.png')) {
                // printLogByFlag(true, '这是一张图片');
                iShowImage = true;
                iShowVideo = false;
                // _pageController.jumpToPage(1);
                startTimer();
              } else {
                iShowImage = false;
                iShowVideo = true;
                playVideo1();
              }
            }
          }
        });
      });
      _controller.setLooping(false);
    });
    _controller.play();
  }

  ///启动Timer
  void startTimer() {
    //间隔五秒时间
    _timer = new Timer.periodic(Duration(milliseconds: 5000), (value) {
      print("定时器");
      currentIndex++;
      // printLogByFlag(true, 'currentIndex:${currentIndex}');
      // printLogByFlag(true, 'currentIndex % imageList.length:${currentIndex % imageList.length}');
       String _currentUrl = imageList[currentIndex % imageList.length];
      // printLogByFlag(true, 'currentUrl:$_currentUrl');
      //触发轮播切换
      if (!_currentUrl.endsWith('.png')) {
        _timer!.cancel();
        // printLogByFlag(true, '这是视频资源');
        setState(()  {
           currentUrl = _currentUrl;
          iShowVideo =true;
          iShowImage = false;
          playVideo1();
           // _pageController.jumpToPage(0);
        });
      } else {
        iShowVideo =false;
        iShowImage = true;
        currentUrl = _currentUrl;
        setState(() {});
      }

    });

  }

  @override
  void dispose() {
    super.dispose();
    _timer?.cancel();
  }

  @override
  void initState() {
    super.initState();
 
    _controller = VideoPlayerController.network('');
    currentUrl = imageList[0];
    // printLogByFlag(true, 'currentUrl:${currentUrl}');
    if(currentUrl.endsWith('.png')){
      // printLogByFlag(true, '这是图片资源');
      //如果是图片则启动定时器
      iShowImage = true;
      iShowVideo = false;
      startTimer();
      setState(() {
      });

    }else{
      // printLogByFlag(true, '这是视频资源');
      playVideo1();
      iShowImage = false;
      iShowVideo = true;
    }
  }

  //定时器自动轮播
  Timer? _timer;

  //当前显示的索引
  int currentIndex = 0;

//通过标记位来控制视频组件的显示或者隐藏
bool iShowVideo = false;
//通过此标记位来控制图片组件的显示或者隐藏
bool iShowImage= false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("视频图片轮播"),
      ),
      body: Container(
        height: double.infinity,
        width: double.infinity,
        child: Stack(
          children: [
            //轮播图片
            Visibility(child:  VideoPlayer(_controller),visible: iShowVideo,),
            Visibility(child:   Image.asset(currentUrl,// fit: BoxFit.fill,
            ),visible: iShowImage,),
          ],
        ),
      ),
    );
  }
}

文章介绍完毕,代码也都比较容易理解,如有疑问可联系笔者交流。
只要思想不滑坡,办法总比困难多。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

無昂博奥

测试下大赏功能,请勿大赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值