Flutter StreamBuilder 实现的一个倒计时功能

Flutter是谷歌推出的最新的移动开发框架。

【x1】微信公众号的每日提醒 随时随记 每日积累 随心而过

【x2】各种系列的视频教程 免费开源 关注 你不会迷路

【x3】系列文章 百万 Demo 随时 复制粘贴 使用


在 Flutter 中可用于异步通信的方案有如下:

本文章讲解 StreamBuilder 的基本使用,以及通过 StreamBuilder实现的计时器的Demo功能

本文章最终实现的效果如下: 在这里插入图片描述 本效果在应用开发中常用于 APP 的开屏广告倒计时页面功能。


首先创建一个 单订阅流控制器 StreamController,通过 WidgetsBinding 来监听 Widget 绘制完成后开启一个 Timer 计时器,代码如下:

///通过流 Stream 实现的倒计时功能
///倒计时
class TestTimeProgressIndicatorPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _TestABPageState();
  }
}

class _TestABPageState extends State {
  ///单订阅流
  StreamController<double> _streamController = StreamController();
  ///计时器
  Timer _timer;
  ///倒计时6秒
  double totalTimeNumber = 6000;
  ///当前的时间
  double currentTimeNumber = 6000;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) { 
      ///当前页面绘制完第一帧后回调
      ///在这里开启定时器
      startTimer();
    });
    
  }


  @override
  void dispose() {
    super.dispose();
    ///关闭
    _streamController.close();
    _timer.cancel();
  }
  ... ...
}
复制代码

Timer 计时器一旦执行了 cancel 方法后,就不可以再次重新覆用,所以在这里封装成了一个方法块,以便多次使用,创建 Timer 计时器的代码如下:

 void startTimer() {
   ///间隔100毫秒执行时间
   _timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
     ///间隔100毫秒执行一次 每次减100
     currentTimeNumber -= 100;

     ///如果计完成取消定时
     if (currentTimeNumber <= 0) {
       _timer.cancel();
       currentTimeNumber = 0;
     }

     ///流数据更新
     _streamController.add(currentTimeNumber);
   });
 }

复制代码

对于页面的主体结构还是使用了 Scaffold 脚手架组件来构建的,代码如下:

@override
 Widget build(BuildContext context) {
   ///页面主体脚手架
   return Scaffold(
     appBar: AppBar(
       title: Text("测试Stream "),
     ),
     body: Column(
       children: [
         
         ///圆圈部分
         Container(
           child: buildStreamBuilder(),
           margin: EdgeInsets.only(top: 20, left: 20),
         ),
         ///间隔
         SizedBox(
           height: 40,
         ),
         
         ///Demo的控制按钮
         OutlineButton(
           child: Text('开始倒计时'),
           onPressed: () {
             currentTimeNumber = totalTimeNumber;
             if (!_timer.isActive) {
               startTimer();
             }
           },
         )
       ],
     ),
   );
 }
复制代码

在这里通过 StreamBuilder 实时来刷新进度与文字显示的,代码如下:

 /// 监听Stream,每次值改变的时候,更新Text中的内容
 StreamBuilder<double> buildStreamBuilder() {
   return StreamBuilder<double>(
     ///绑定stream
     stream: _streamController.stream,
     ///默认的数据
     initialData: 0,
     ///构建绑定数据的UI
     builder: (BuildContext context, AsyncSnapshot<double> snapshot) {
       return Stack(
         ///子Widget 居中对齐
         alignment: Alignment.center,
         children: [
           ///中间显示的文本
           Text(
             (snapshot.data / 1000).toStringAsFixed(0),
             style: TextStyle(fontSize: 22, color: Colors.blue),
           ),
           ///圆圈进度
           CircularProgressIndicator(
             value: 1.0 - snapshot.data / totalTimeNumber,)
         ],
       );
     },
   );
 }
复制代码

运行调试效果如下:

在这里插入图片描述


完毕

以小编的性格,要实现百万Demo随时复制粘贴肯定是需要源码的

当然以小编的性格,肯定是要有视频录制的,目前正在录制中,你可以关注一下 西瓜视频 --- 早起的年轻人 随后会上传


作者:早起的年轻人
链接:https://juejin.cn/post/6886313178397933576
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值