Flutter 快速上手定时器/倒计时及实战讲解
本文微信公众号「AndroidTraveler」首发。
今天给大家讲讲 Flutter 里面定时器/倒计时的实现。
一般有两种场景:
- 我只需要你在指定时间结束后回调告诉我。回调只需要一次。
- 我需要你在指定时间结束后回调告诉我。回调可能多次。
下面针对这两种场景,我们来说下如何在 Flutter 里面使用。
回调一次的定时器
const timeout = const Duration(seconds: 5);
print('currentTime='+DateTime.now().toString());
Timer(timeout, () {
//到时回调
print('afterTimer='+DateTime.now().toString());
});
这里我们设置了超时时间为 5 秒。然后启动一个定时器,等到 5 秒时候到了,就会执行回调方法。
我们在定时器启动之前和之后都加上了打印日志,控制台打印输出如下:
flutter: currentTime=2019-06-08 13:56:35.347493
flutter: afterTimer=2019-06-08 13:56:40.350412
用法总结起来就是:
1.设置超时时间 timeout
2.启动定时器 Timer(timeout, callback)
3.处理回调 callback
回调多次的定时器
回调多次的定时器用法和回调一次的差不多,区别有下面两点:
- 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 次。
控制台输出如下:
flutter: currentTime=2019-06-08 14:16:02.906858
flutter: afterTimer=2019-06-08 14:16:03.909963
flutter: afterTimer=2019-06-08 14:16:04.910538
flutter: afterTimer=2019-06-08 14:16:05.911942
flutter: afterTimer=2019-06-08 14:16:06.911741
flutter: afterTimer=2019-06-08 14:16:07.910227
用法总结起来就是:
1.设置周期回调时间 period
2.启动定时器 Timer.periodic(period, callback(timer))
3.处理回调 callback(timer)
4.记得在合适时机取消定时器,否则会一直回调
好了,有了上面的知识储备,接下来,让我们进入实战讲解环节。
实战讲解
业务场景
服务器返回一个时间,你根据服务器的时间和当前时间的对比,显示倒计时,倒计时的时间在一天之内,超过一天显示默认文案即可。
场景分析
这个业务场景在倒计时这一块就需要使用到我们上面的知识了。由于限定了倒计时是在一天之内,所以显示的文案就是从 00:00:00 到 23:59:59。
具体代码操作
基本思路:首先我们需要获得剩余时间,接着启动一个 1 秒的周期性定时器,然后每隔一秒更新一下文案。
直接上代码:
//时间格式化,根据总秒数转换为对应的 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();
}
//获取当期时间
var now = DateTime.now();
//获取 2 分钟的时间间隔
var twoHours = now.add(Duration(minutes: 2)).difference(now);
//获取总秒数,2 分钟为 120 秒
var seconds = twoHours.inSeconds;
//设置 1 秒回调一次
const period = const Duration(seconds: 1);
//打印一开始的时间格式,为 00:02:00
print(constructTime(seconds));
Timer.periodic(period, (timer) {
//秒数减一,因为一秒回调一次
seconds--;
//打印减一后的时间
print(constructTime(seconds));
if (seconds == 0) {
//倒计时秒数为0,取消定时器
timer.cancel();
timer = null;
}
});
其实注释也写的很清楚了,就是基本思路的基础上增加了一些细节处理,这里演示是自己构造了一个两分钟的倒计时。
好了,基本到这里已经说完了,但是可能 Flutter 具体一些细节还不一样,这边直接给下一个倒计时的完整代码吧。
import 'dart:async';
import 'package:flutter/material.dart';
class Countdown extends StatefulWidget {
@override
_CountdownState createState() => _CountdownState();
}
class _CountdownState extends State<Countdown> {
Timer _timer;
int seconds;
@override
Widget build(BuildContext context) {
return Center(
child: Text(constructTime(seconds)),
);
}
//时间格式化,根据总秒数转换为对应的 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();
}
@override
void initState() {
super.initState();
//获取当期时间
var now = DateTime.now();
//获取 2 分钟的时间间隔
var twoHours = now.add(Duration(minutes: 2)).difference(now);
//获取总秒数,2 分钟为 120 秒
seconds = twoHours.inSeconds;
startTimer();
}
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() {
super.dispose();
cancelTimer();
}
}
效果如下:

后续打算写一个 FlutterApp 涵盖我之前博客的例子,方便大家结合代码查看实际运行效果,敬请期待。
这边之前创建了一个知识星球,欢迎互联网小伙伴加入,一起学习,共同成长。
链接方式加入:
我正在「Flutter(限免)」和朋友们讨论有趣的话题,你一起来吧?
https://t.zsxq.com/MVrJiAY
扫码方式加入:


Flutter 快速上手定时器/倒计时及实战讲解的更多相关文章
- Spring Boot 揭秘与实战(一) 快速上手
文章目录 1. 简介 1.1. 什么是Spring Boot 1.2. 为什么选择Spring Boot 2. 相关知识 2.1. Spring Boot的spring-boot-starter 2. ...
- 学习Keras:《Keras快速上手基于Python的深度学习实战》PDF代码+mobi
有一定Python和TensorFlow基础的人看应该很容易,各领域的应用,但比较广泛,不深刻,讲硬件的部分可以作为入门人的参考. <Keras快速上手基于Python的深度学习实战>系统 ...
- 【学习总结】快速上手Linux玩转典型应用-第7章-WebServer安装和配置讲解
课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. Apache的安装 2. Apache的虚拟主机配置及伪静态操作 3. Nginx的基本操作 4. Nginx伪静态的实现 5. 实例演 ...
- 【学习总结】快速上手Linux玩转典型应用-第6章-linux常用命令讲解
课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. 软件操作命令 2. 服务器硬件资源信息 3. 文件操作命令 4. Linux文本编辑神器vim与其他常用命令 5. 系统用户操作命令 6 ...
- 【RL-TCPnet网络教程】第3章 初学RL-TCPnet的准备工作及其快速上手
第3章 初学RL-TCPnet的准备工作及其快速上手 俗话说万事开头难,学习一门新的知识,难的往往不是知识本身,而是如何快速上手,需要什么资料和开发环境.一旦上手后,深入的学习就相对容易些 ...
- 【Python五篇慢慢弹】快速上手学python
快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...
- NHibernate3快速上手教程FluentNHibernate配置与DBHelper
很多学习NHibernate的新手很容易卡在配置文件这一关,正所谓万事开头难,上手后再配合官方文档就比较容易了. 网上关于配置文件的资料非常多,但由于版本的问题,许多老的教程中都没有明确指出类库的版本 ...
- 快速上手RaphaelJS-Instant RaphaelJS Starter翻译(一)
(目前发现一些文章被盗用的情况,我们将在每篇文章前面添加原文地址,本文源地址:http://www.cnblogs.com/idealer3d/p/Instant_RaphaelJS_Start ...
- UnityShader快速上手指南(一)
简介 引言 其实网上有很多shader教程,但是大概看了下,也不知是网上各位大神已经脱离了代码层面的高度还是啥原因.貌似没有找到从代码方面作为入门讲解的,导致了shader对于苦逼程序员入门有一定要求 ...
随机推荐
- 【实用工具】使用Java封装可执行exe应用全过程
目录 编写java代码 打包 创建exe文件 压缩 总结 本文将使用exe4j将java项目封装为可以发送给他人使用的工具为例,来记录将java项目封装为exe文件的全过程 编写java代码 目标:创 ...
- react-native-linear-gradient颜色渐变
目录 一 安装 二 使用 2.1 colors 2.2 start / end eg1:斜角渐变 eg2: 从左到右 2.2 locations eg1: 0.4是渐变的起点,0.6是渐变的终点 一 ...
- 压缩感知重构算法之OMP算法python实现
压缩感知重构算法之OMP算法python实现 压缩感知重构算法之CoSaMP算法python实现 压缩感知重构算法之SP算法python实现 压缩感知重构算法之IHT算法python实现 压缩感知重构 ...
- 带你从头到尾捋一遍MySQL索引结构(2)
前言 Hello我又来了,快年底了,作为一个有抱负的码农,我想给自己攒一个年终总结.索性这次把数据库中最核心的也是最难搞懂的内容,也就是索引,分享给大家. 这篇博客我会谈谈对于索引结构我自己的看法,以 ...
- JavaScript2 基础
运算符 赋值运算符 用于给变量赋值. y=5;/z=2; 算术运算符 即算数符号,是基本算数运算.+ 加 / - 减/ * 乘/ / 除/ % 取余数/ ++ 自增(y++先赋值再自增/++y先自 ...
- Spring源码学习笔记之基于ClassPathXmlApplicationContext进行bean标签解析
bean 标签在spring的配置文件中, 是非常重要的一个标签, 即便现在boot项目比较流行, 但是还是有必要理解bean标签的解析流程,有助于我们进行 基于注解配置, 也知道各个标签的作用,以及 ...
- ZOJ 2112 Dynamic Rankings(树状数组+主席树)
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
- HDU-6119
度度熊喜欢着喵哈哈村的大明星——星星小姐. 为什么度度熊会喜欢星星小姐呢? 首先星星小姐笑起来非常动人,其次星星小姐唱歌也非常好听. 但这都不是最重要的,最重要的是,星星小姐拍的一手好代码! 于是度度 ...
- HDU3870-Caught these thieves(最小割->偶图->最短路问题)
A group of thieves is approaching a museum in the country of zjsxzy,now they are in city A,and the m ...
- usb2.0高速视频采集之68013A寄存器配置说明
任何的固件编程离不开与与原理图参考,图纸中所采用的是USB的Slave_fifo传输方式,具体配置与图纸对应即可. •USB_IFCLK:同步Slave_FIFO模式,输入频率范围5M-48M,在FP ...