赞
踩
倒计时/定时器在移动应用开发中比较常见的功能,比如启动时的广告倒计时、比如弹框倒计时、比如定时1秒后跳转、获取验证码等等。今天就认识一下Flutter中的倒计时/定时器。
一般有两种场景:
我只需要你在指定时间结束后回调告诉我。回调只需要一次。
我需要你在指定时间结束后回调告诉我。回调可能多次。
Timer 类存在于dart:async内,所以我们需要先导入
import 'dart:async';
Timer 的构造也很简单,一个时长Duration 一个到时之后执行的任务callback,如下图,他的构造方法
const timeout = const Duration(seconds: 5);
print('currentTime ='+DateTime.now().toString());
Timer(timeout, () {
//到时回调
print('after 5s Time ='+DateTime.now().toString());
});
这里我们设置了超时时间为 5 秒。然后启动一个定时器,等到 5 秒时候到了,就会执行回调方法。
我们在定时器启动之前和之后都加上了打印日志,控制台打印输出如下:
I/flutter (15245): currentTime =2019-07-17 13:58:52.281287
I/flutter (15245): after 5s Time =2019-07-17 13:58:57.284234
回调多次的定时器用法和回调一次的差不多,区别有下面两点:
API 调用不同
需要手动取消,否则会一直回调,因为是周期性的
int count = 0;
const period = const Duration(seconds: 1);
print('currentTime='+DateTime.now().toString());
Timer.periodic(period, (timer) {
//到时回调
print('afterTimer='+DateTime.now().toString());
count++;
if (count >= 5) {
//取消定时器,避免无限回调
timer.cancel();
timer = null;
}
});
这里我们的功能是每秒回调一次,当达到 5 秒后取消定时器,一共 回调了 5 次。
控制台输出如下:
I/flutter (15245): currentTime=2019-07-17 14:07:21.147541
I/flutter (15245): afterTimer=2019-07-17 14:07:22.166514
I/flutter (15245): afterTimer=2019-07-17 14:07:23.165105
I/flutter (15245): afterTimer=2019-07-17 14:07:24.165862
I/flutter (15245): afterTimer=2019-07-17 14:07:25.167847
I/flutter (15245): afterTimer=2019-07-17 14:07:26.165679
注意⚠️:得在合适时机取消定时器,否则会一直回调
服务器返回一个时间,你根据服务器的时间和当前时间的对比,显示倒计时,倒计时的时间在一天之内,超过一天显示默认文案即可。在一天之内,所以显示的文案就是从 00:00:00 到 23:59:59。
首先我们需要获得剩余时间,接着启动一个 1 秒的周期性定时器,然后每隔一秒更新一下文案。此外还加了开始和停止的逻辑。
import 'package:flutter/material.dart'; import 'dart:async'; class TimerTest extends StatefulWidget { TimerTest({Key key, this.title}) : super(key: key); final String title; @override createState() => new _TimerTestState(); } class _TimerTestState extends State<TimerTest> { Timer _timer; int seconds = 0; bool _timeState = true; String _title = 'start'; String _content = '00:00:00'; @override Widget build(BuildContext context) { print('build'); _content = constructTime(seconds); return new Scaffold( appBar: new AppBar( title: new Text('Timer test'), ), body: Center( child:Column( children: <Widget>[ SizedBox(height:25.0), Text("定时器倒计时练习"), SizedBox(height: 25.0), RaisedButton( onPressed: _incrementCounter, child: new Text('只执行一次'), ), SizedBox(height: 20.0), RaisedButton( onPressed: _tickTest, child: new Text('周期性Tick'), ), SizedBox(height: 20.0), RaisedButton( onPressed: countDownTest, child: new Text('$_title'), ), SizedBox(height: 20.0), Text("$_content",style: TextStyle(color: Colors.red,fontSize: 30),), ], ), ), ); } //时间格式化,根据总秒数转换为对应的 hh:mm:ss 格式 String constructTime(int seconds) { int hour = seconds ~/ 3600; int minute = seconds % 3600 ~/ 60; int second = seconds % 60; return formatTime(hour) + ":" + formatTime(minute) + ":" + formatTime(second); } //数字格式化,将 0~9 的时间转换为 00~09 String formatTime(int timeNum) { return timeNum < 10 ? "0" + timeNum.toString() : timeNum.toString(); } // 初始化方法。先于build执行 @override void initState() { super.initState(); print('initState'); } void countDownTest(){ _timeState = !_timeState; setState(() { if (_timeState) { _title = 'start'; } else { _title = 'stop'; } }); if (!_timeState) { //获取当期时间 var now = DateTime.now(); //获取 2 分钟的时间间隔 var twoHours = now.add(Duration(minutes: 2)).difference(now); //获取总秒数,2 分钟为 120 秒 seconds = twoHours.inSeconds; startTimer(); } else { seconds = 0; cancelTimer(); } } void startTimer() { //设置 1 秒回调一次 const period = const Duration(seconds: 1); _timer = Timer.periodic(period, (timer) { //更新界面 setState(() { //秒数减一,因为一秒回调一次 seconds--; }); if (seconds == 0) { //倒计时秒数为0,取消定时器 cancelTimer(); } }); } void cancelTimer() { if (_timer != null) { _timer.cancel(); _timer = null; } } @override void dispose() { cancelTimer(); // 相当于dealloc super.dispose(); } } void _incrementCounter() { const timeout = const Duration(seconds: 5); print('currentTime ='+DateTime.now().toString()); Timer(timeout, () { //到时回调 print('after 5s Time ='+DateTime.now().toString()); }); } _tickTest() { int count = 0; const period = const Duration(seconds: 1); print('currentTime='+DateTime.now().toString()); Timer.periodic(period, (timer) { //到时回调 print('afterTimer='+DateTime.now().toString()); count++; if (count >= 5) { //取消定时器,避免无限回调 timer.cancel(); timer = null; } }); }
效果如下:
总结:setState(){} 谁变set谁。这里set seconds
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。