Flutter 轮子:视频广告倒计时页面

Flutter 轮子:视频广告倒计时页

用不了多久,你就会和我一样明白,每个人都要经历属于自我的起起落落,我们的那些孤独、彷徨、失落,无人能懂,但人人都会体验,那些最初无法忍受的情绪,不必深究不用纪念,真正需要铭记的,是身边陪伴你的人事,是爱。

先来看看今天要完成的效果吧:

效果图(1.1):

分析:

  • 背景视屏动画
  • 右上角白色框圆角倒计时
  • 当按钮为0时完成跳转页面
  • 当点击按钮时完成跳转页面

仿照的是视频动画广告页,视频为KFC广告

背景视频

video_player 1.0.1

官方例子:

import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';

void main() => runApp(VideoApp());

class VideoApp extends StatefulWidget {
  @override
  _VideoAppState createState() => _VideoAppState();
}

class _VideoAppState extends State<VideoApp> {
  VideoPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.network(
        'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4')
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {});
      });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video Demo',
      home: Scaffold(
        body: Center(
          child: _controller.value.initialized
              ? AspectRatio(
                  aspectRatio: _controller.value.aspectRatio,
                  child: VideoPlayer(_controller),
                )
              : Container(),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              _controller.value.isPlaying
                  ? _controller.pause()
                  : _controller.play();
            });
          },
          child: Icon(
            _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }
}

可以看出:

  • VideoPlayerController.network()是加载的网络视频
  • VideoPlayerController.asset()是加载的本地视频

通过控制器参数可以控制视屏是否播放:

  • _controller.pause() 暂停动画
  • _controller.play() 开始动画

官方效果图:效果图(1.2):

效果图(1.2):

官方使用的是网络视频,一般视频广告页都是用的本地视频

咋们稍微修改一下代码,使用本地视频:

在这里插入图片描述
视频地址在这里

创建assets文件夹,并创建video文件夹,吧咋们准备好的视频放到里面并在pubspec.xml中声明;

pubspec.xml:

  assets:
     - assets/video/

VideoPlayerWidget:

import 'package:flutter/material.dart';
import 'package:flutter_trip/tests/video_page_widget.dart';
import 'package:video_player/video_player.dart';

class VideoPlayerWidget extends StatefulWidget {
  String url;

  ///VideoPageEnum.asset 本地视屏  默认
  /// VideoPageEnum.network 网络视频
  VideoPageEnum type;

  VideoPlayerWidget({@required this.url, this.type  = VideoPageEnum.asset});

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

class _VideoPlayerWidgetState extends State<VideoPlayerWidget> {
  VideoPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller =
    widget.type == VideoPageEnum.asset
        ? VideoPlayerController.asset(widget.url)
        : VideoPlayerController.network(widget.url)
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {});
      });
      //开始视频
    _controller.play();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
	    //占满全屏
        width: double.infinity,
        height: double.infinity,
        child: AspectRatio(
          aspectRatio: _controller.value.aspectRatio,
          child: VideoPlayer(_controller),
        ));
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }
}

这个页面有2个参数;

  • url 本地路径或者网络路径(必传参数)
  • type:视屏类型(默认是本地)
    • VideoPageEnum.asset 本地视屏
    • VideoPageEnum.network 网络视频

因为视频和倒计时是同一个页面,所以咋们创建一个Widget来调用他:

VideoPageWidget 页面:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_trip/tests/video_player_text.dart';
import 'package:flutter_trip/util/log_util.dart';
import 'package:flutter_trip/util/navigator_util.dart';
import 'package:flutter_trip/util/toast.dart';

class VideoPageWidget extends StatefulWidget {
  String url;
  int time; //默认5s

  ///VideoPageEnum.asset 本地视屏
  /// VideoPageEnum.network 网络视频
  VideoPageEnum type;
  Widget widget;

  /// [url] 路径地址
  /// [time] 倒计时时间
  /// [type] VideoPageEnum.asset本地视频(默认)  VideoPageEnum.network 网络视频
  /// [widget] 要跳转的页面
  VideoPageWidget({
    @required this.url,
    this.time = 5,
    this.type = VideoPageEnum.asset,
    @required this.widget,
  });

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

class _VideoPageWidgetState extends State<VideoPageWidget> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          //视屏播放
          VideoPlayerWidget(url: widget.url, type: widget.type),

          //右上角跳转
         Positioned(...),
        ],
      ),
    );
  }
}

enum VideoPageEnum {
  //本地视频 通过assets下的video引用
  asset,
  // 网络 视频
  network
}

参数介绍:

  • [url] 路径地址(必传参数)
  • [time] 倒计时时间(默认5s)
  • [type] 视频类型(默认本地视频)
    • VideoPageEnum.asset本地视频
    • VideoPageEnum.network 网络视频
  • [widget] 要跳转的页面(必传参数)

效果图(1.3):

倒计时

倒计时可点击布局:

	 Positioned(
            child: GestureDetector(
                onTap: () {
                  goHome();
                }, // 倒计时按钮布局
                child: buildContainer(context)),
            right: 20,
            top: 40,
          ),
          
   //倒计时按钮布局
  Widget buildContainer(BuildContext context) {
    return Container(
      width: 100,
      height: 30,
      decoration: BoxDecoration(
          border: Border.all(
            color: Colors.white,
            width: 2,
          ),
          borderRadius: BorderRadius.all(Radius.circular(15))),
      alignment: Alignment.center,
      child: Text(
        '${widget.time}s',
        style: TextStyle(color: Colors.white, fontSize: 16),
      ),
    );
  }    
  
//跳转到Home页面
//NavigatorUtil使用的是工具类
 void goHome() {
    NavigatorUtil.pushColsePage(
      context: context,
      widget: widget.widget,
    );
  }

这段代码还是比较简单的,这里要说的就是

  • widget.widget 要跳转的页面
  • widget.time 倒计时时间

在State中widget.属性就是和State绑定的Widget

class VideoPageWidget extends StatefulWidget {
  String url;
  int time; //默认5s

  ///VideoPageEnum.asset 本地视屏
  /// VideoPageEnum.network 网络视频
  VideoPageEnum type;
  Widget widget;
  VideoPageWidget({
    @required this.url,
    this.time = 5,
    this.type = VideoPageEnum.asset,
    @required this.widget,
  });
  @override
  _VideoPageWidgetState createState() => _VideoPageWidgetState();
}
class _VideoPageWidgetState extends State<VideoPageWidget> {
    ........
}

这里State绑定的是VideoPageWidget

所以widget.就是.的VideoPageWidget中的属性

效果图(1.4):

Timer倒计时效果

Timer _timer;

  @override
  void initState() {
    super.initState();
    //1s执行一下
    _timer = Timer.periodic(new Duration(seconds: 1), (value) {
      if (widget.time == 1) {
        //关闭
        _timer.cancel();
        goHome();
      }
      widget.time--;
      setState(() {});
      print("time: ${widget.time}");
    });
  }

  @override
  void dispose() {
    //计时器是否是活动状态
    if (_timer.isActive) {
      _timer.cancel();
    }
    super.dispose();
  }

分析:

Timer.periodic(new Duration(seconds: 1), (value) {}

通过这个方法来来1s执行一下,当执行到

 if (widget.time == 1) {
  _timer.cancel();
}

widget.time == 1时,让_timer停止,并每次刷新数据,完成数据的倒计时效果

切记,一定要在销毁时销毁Timer哦

  @override
  void dispose() {
    //计时器是否是活动状态
    if (_timer.isActive) {
      _timer.cancel();
    }
    super.dispose();
  }

Video+倒计时页面:VideoPageWidget

Video页面:VideoPlayerWidget

视频地址在这里

NavigatorUtil

官方代码

完整代码

猜你喜欢:

Flutter 小知识,动态权限申请工具类

原创不易,您的点赞就是对我最大的支持,留下您的点赞吧~



下面是我的公众号,平时会发一些andoridflutter 的小知识等,主要用来记录工作开发中的一些小知识,有喜欢的朋友可以扫描二维码咋们互相进步~

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

s10g

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值