本文微信公众号「AndroidTraveler」首发。

今天给大家讲讲 Flutter 里面定时器/倒计时的实现。

一般有两种场景:

  1. 我只需要你在指定时间结束后回调告诉我。回调只需要一次。
  2. 我需要你在指定时间结束后回调告诉我。回调可能多次。

下面针对这两种场景,我们来说下如何在 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

回调多次的定时器

回调多次的定时器用法和回调一次的差不多,区别有下面两点:

  1. API 调用不同
  2. 需要手动取消,否则会一直回调,因为是周期性的

一样的我们通过一个简单的小例子来说明:

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 快速上手定时器/倒计时及实战讲解的更多相关文章

  1. Spring Boot 揭秘与实战(一) 快速上手

    文章目录 1. 简介 1.1. 什么是Spring Boot 1.2. 为什么选择Spring Boot 2. 相关知识 2.1. Spring Boot的spring-boot-starter 2. ...

  2. 学习Keras:《Keras快速上手基于Python的深度学习实战》PDF代码+mobi

    有一定Python和TensorFlow基础的人看应该很容易,各领域的应用,但比较广泛,不深刻,讲硬件的部分可以作为入门人的参考. <Keras快速上手基于Python的深度学习实战>系统 ...

  3. 【学习总结】快速上手Linux玩转典型应用-第7章-WebServer安装和配置讲解

    课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. Apache的安装 2. Apache的虚拟主机配置及伪静态操作 3. Nginx的基本操作 4. Nginx伪静态的实现 5. 实例演 ...

  4. 【学习总结】快速上手Linux玩转典型应用-第6章-linux常用命令讲解

    课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. 软件操作命令 2. 服务器硬件资源信息 3. 文件操作命令 4. Linux文本编辑神器vim与其他常用命令 5. 系统用户操作命令 6 ...

  5. 【RL-TCPnet网络教程】第3章 初学RL-TCPnet的准备工作及其快速上手

    第3章       初学RL-TCPnet的准备工作及其快速上手 俗话说万事开头难,学习一门新的知识,难的往往不是知识本身,而是如何快速上手,需要什么资料和开发环境.一旦上手后,深入的学习就相对容易些 ...

  6. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  7. NHibernate3快速上手教程FluentNHibernate配置与DBHelper

    很多学习NHibernate的新手很容易卡在配置文件这一关,正所谓万事开头难,上手后再配合官方文档就比较容易了. 网上关于配置文件的资料非常多,但由于版本的问题,许多老的教程中都没有明确指出类库的版本 ...

  8. 快速上手RaphaelJS-Instant RaphaelJS Starter翻译(一)

       (目前发现一些文章被盗用的情况,我们将在每篇文章前面添加原文地址,本文源地址:http://www.cnblogs.com/idealer3d/p/Instant_RaphaelJS_Start ...

  9. UnityShader快速上手指南(一)

    简介 引言 其实网上有很多shader教程,但是大概看了下,也不知是网上各位大神已经脱离了代码层面的高度还是啥原因.貌似没有找到从代码方面作为入门讲解的,导致了shader对于苦逼程序员入门有一定要求 ...

随机推荐

  1. Internet History,Technology,and Security - Dawn of Electronic Computing(Week 1)

    一 War Time Computing and Communication 讲到电子计算机,你不得不提起第二次世界大战,虽说二战是人类历史上史无前例的大灾难,不过从某种程度来说,它确实促进了社会的发 ...

  2. GROUP_CONCAT在组合商品中的使用

    表:combined_product_item -------------------------pid sku quality-------------------------1 sku1 11 s ...

  3. git 使用详解(2)——安装+配置+获取帮助

    安装 Git Git 有许多种安装方式,主要分为两种,一种是通过编译源代码来安装:另一种是使用为特定平台预编译好的安装包. 从源代码安装 若是条件允许,从源代码安装有很多好处,至少可以安装最新的版本. ...

  4. [TimLinux] JavaScript table的td内容超过宽度缩为三个点

    1. 思路 CSS控制td内容自动缩为三个点 JS控制鼠标悬浮显示td全部内容 2. 实现 HTML代码: <!DOCTYPE html> <html> <head> ...

  5. LightOJ 1229 Tablecross

    Treblecross is a two player game where the goal is to get three X in a row on a one-dimensional boar ...

  6. 拓展KMP分析

    拓展kmp是对KMP算法的扩展,它解决如下问题: 定义母串S,和字串T,设S的长度为n,T的长度为m,求T与S的每一个后缀的最长公共前缀,也就是说,设extend数组,extend[i]表示T与S[i ...

  7. Codeves-5037线段树4加强版(线段树? 。。。分块)

    维护一个序列,要求支持下列2种操作: add a b c:区间[a,b]中每个数加上c count a b:查询区间[a,b]中有多少数是k的倍数(k为给定常数) 输入描述 Input Descrip ...

  8. (全国多校重现赛一) J-Two strings

    Giving two strings and you should judge if they are matched.  The first string contains lowercase le ...

  9. 【Webpack】319- Webpack4 入门手册(共 18 章)(上)

    介绍 1. 背景 最近和部门老大,一起在研究团队[EFT - 前端新手村]的建设,目的在于:帮助新人快速了解和融入公司团队,帮助零基础新人学习和入门前端开发并且达到公司业务开发水平. 本文也是属于[E ...

  10. 基于Storm的WordCount

    Storm WordCount 工作过程 Storm 版本: 1.Spout 从外部数据源中读取数据,随机发送一个元组对象出去: 2.SplitBolt 接收 Spout 中输出的元组对象,将元组中的 ...