[Flutter]倒计时和计时器

1.延迟执行

Future.delayed

使用Future.delayed可以在延迟一定时间后执行代码。这是实现延迟执行最简单的方式之一。

Future.delayed(Duration(seconds: 1), () {// 这里的代码会在1秒后执行print('This message is displayed after 1 second.');
});

Timer

Timer类提供了更灵活的方式来实现单次或重复的延迟执行。

// 单次延迟
Timer(Duration(seconds: 1), () {// 这里的代码会在1秒后执行print('This message is displayed after 1 second.');
});// 重复执行
Timer.periodic(Duration(seconds: 1), (Timer t) {// 这里的代码会每1秒执行一次print('This message is displayed every 1 second.');
});

AnimationController

在动画中,使用AnimationController可以在动画帧更新时执行代码,这可以用来实现延迟。

AnimationController controller = AnimationController(duration: Duration(seconds: 1),vsync: this, // 需要一个TickerProvider类型的vsync参数
);controller.forward().then((_) {// 这里的代码会在动画结束后执行print('This message is displayed after the animation ends.');
});

Future

如果你已经在处理Future,也可以通过.then()链式调用在Future完成后延迟执行代码。

someFuture().then((value) {// 做一些处理...
}).then((_) {// 这里的代码会紧接着前一个then执行后执行print('This message is displayed after the future completes.');
});

使用async和await

结合使用asyncawait关键字,可以让你在异步函数中顺序执行代码块,看起来像是同步代码。

Future<void> delayedPrint() async {await Future.delayed(Duration(seconds: 1));print('This message is displayed after 1 second.');
}delayedPrint();

进一步封装一下

class Tools {// 延迟执行static void delayExecution(int second, void Function() callback) async {await Future.delayed(Duration(seconds: second));callback();}
}Tools.delayExecution(3, () {print("execute");
});

Isolates

当需要执行长时间运行的计算任务时,可以使用Isolates来实现不阻塞主线程的延迟执行。这在Flutter中用于并行计算或执行耗时任务。

import 'dart:isolate';void longRunningTask(SendPort sendPort) {// 执行耗时任务sendPort.send(result);
}void startIsolate() async {ReceivePort receivePort = ReceivePort();Isolate.spawn(longRunningTask, receivePort.sendPort);receivePort.listen((data) {// 获取到结果后执行的操作});
}

在实际应用中,选择哪种方式取决于你的具体需求。对于简单的延迟执行,通常Future.delayedTimer就足够使用。而对于涉及动画或者复杂异步流程的情况,则可能需要使用AnimationController或者结合asyncawait的方式。对于需要后台执行的长时间运行任务,则可能需要使用Isolate

 

2.全局控制的倒计时

要创建一个全局定时器,可以通过单例模式封装一个定时器管理类。这个类可以提供启动、暂停、重启和关闭定时器的方法,并且确保定时完成后自动释放定时器资源。

以下是一个简单的全局定时器管理类示例:

import 'dart:async';class GlobalTimer {static final GlobalTimer _instance = GlobalTimer._internal();Timer? _timer;factory GlobalTimer() {return _instance;}GlobalTimer._internal();void startTimer({required Duration delay,required VoidCallback action,}) {_timer?.cancel(); // 取消之前的计时器(如果存在)_timer = Timer(delay, () {action();// 计时器执行完成后释放资源_timer?.cancel();_timer = null;});}void pauseTimer() {if (_timer?.isActive ?? false) {_timer?.cancel();}}void resumeTimer({required Duration delay,required VoidCallback action,}) {pauseTimer(); // 先暂停计时器startTimer(delay: delay, action: action); // 重新开始计时器}void stopTimer() {_timer?.cancel();_timer = null;}bool isTimerActive() {return _timer?.isActive ?? false;}
}

使用:

// 启动定时器
GlobalTimer().startTimer(delay: Duration(seconds: 5),action: () {print('Timer action executed after 5 seconds');},
);// 暂停定时器
GlobalTimer().pauseTimer();// 重启定时器
GlobalTimer().resumeTimer(delay: Duration(seconds: 5),action: () {print('Timer action executed after another 5 seconds');},
);// 停止定时器
GlobalTimer().stopTimer();// 检查定时器是否活跃
bool isActive = GlobalTimer().isTimerActive();

这个类使用了单例模式,确保全局只有一个GlobalTimer实例。startTimer方法用于设置定时器,接收延迟时间和要执行的动作。pauseTimer会暂停定时器,resumeTimer可以重启定时器,而stopTimer会停止定时器并释放资源。isTimerActive方法用于检查定时器是否在运行中。

这个类不是线程安全的,因为Dart本身是单线程的,但是如果你使用它在Flutter的Isolates(类似于线程)中,请确保你正确地管理状态。此外,如果你的应用需要更复杂的定时器调度,你可能需要考虑其他的包或者解决方案。

 

3.全局控制的计时器

要创建一个全局可控的计时器,你可以使用单例模式并结合StreamStreamController来实现计时器状态的全局订阅。这样,你可以在任何地方订阅计时器的变化,并实现回调更新。

以下是一个实现全局计时器的示例:

import 'dart:async';class GlobalTimer {static final GlobalTimer _instance = GlobalTimer._internal();Timer? _timer;int _elapsedSeconds = 0;final StreamController<int> _streamController = StreamController<int>.broadcast();DateTime? _startTime;factory GlobalTimer() {return _instance;}GlobalTimer._internal();void startTimer() {if (_timer != null && _timer!.isActive) {// 如果计时器已经启动,则不做任何操作return;}_startTime = DateTime.now(); // 记录开始计时的时间戳_timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {_elapsedSeconds++;_streamController.add(_elapsedSeconds); // 通过Stream通知订阅者});}void stopTimer() {_timer?.cancel();_timer = null;_elapsedSeconds = 0; // 重置累计时间_startTime = null;}int get elapsedSeconds => _elapsedSeconds;Stream<int> get timerStream => _streamController.stream;static String formatDuration(int totalSeconds) {int hours = totalSeconds ~/ 3600;int minutes = (totalSeconds % 3600) ~/ 60;int seconds = totalSeconds % 60;String hoursStr = (hours).toString().padLeft(2, '0');String minutesStr = (minutes).toString().padLeft(2, '0');String secondsStr = (seconds).toString().padLeft(2, '0');return "$hoursStr:$minutesStr:$secondsStr";}void dispose() {_streamController.close();}
}

使用:

// 启动计时器
GlobalTimer().startTimer();// 停止计时器
GlobalTimer().stopTimer();// 获取当前累计计时时长
int seconds = GlobalTimer().elapsedSeconds;// 格式化计时显示
String formattedTime = GlobalTimer.formatDuration(seconds);// 订阅计时变化
GlobalTimer().timerStream.listen((int elapsedSeconds) {print('Timer updated: $elapsedSeconds seconds');// 更新页面等...
});// 释放资源
GlobalTimer().dispose();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710056.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20240227-Python Tkinter学习笔记

文章目录 Label标签Label标签和Button按钮Listbox列表Radiobutton单选按钮Scale滑动条Checkbutton多选框Canvas画布Menubar 菜单Frame框架Messagebox弹窗pack/grid/place 布局方式登录注册案例 Label标签 import tkinter as tk # 导入tkinter模块&#xff0c;并简写为tk# 创建…

mysql数据库安装与使用(一)

目录 前言 一&#xff0c;安装mysql数据库 二&#xff0c;mysql数据库使用 连接mysql数据库 创建数据库 创建表格 插入数据 查询数据 更新数据 删除数据 关闭连接 使用数据库 查看所有数据库 查看数据库中的表 三&#xff0c;mysql设置 创建用户 授予权限 刷新权…

全量知识系统问题及SmartChat给出的答复 之3

Q8. 进一步&#xff0c;请展示如何使用这些技术来衡量、评估或适应不可避免的不匹配的知识汤问题的更进一步的全面代码。 为了处理不可避免的不匹配的知识汤问题&#xff0c;我们可以引入一些技术方法来衡量、评估或适应这种情况。 下是一个更进一步的全面代码示例&#xff0…

代码随想录算法训练营Day30|332.重新安排行程、51. N皇后、37. 解数独

332.重新安排行程 题目链接&#xff1a;332.重新安排行程 文档链接&#xff1a;332.重新安排行程 C实现 class Solution { private:unordered_map<string,map<string,int>> targets;bool backtracking(int ticketNum, vector<string>& result) {if(resu…

怎么制作文件类型二维码?文件二维码如何加密?

现在将文件转二维码图片后&#xff0c;分享生成二维码来扫码查看或者下载文件的方式&#xff0c;在很多的场景中都有应用。这个方法的优势在于&#xff0c;成本低而且安全性高&#xff0c;有利于用户快速获取内容的速度&#xff0c;有效提高用户体验&#xff0c;而且日常使用的…

【Kubernetes】服务(Service)是什么?有什么用?有哪些类型?

系列文章目录 K8s中的Namespace是什么&#xff1f; Kubernetes 集群的组件介绍 Kubernetes 对象是什么&#xff1f; Pod——k8s中最重要的对象之一 Kubernetes 和 Docker 之间有什么区别&#xff1f; 部署安装 K8s 为什么要关闭 swap 分区&#xff1f; k8s中容器之间、pod之间…

ZABBIX修改web界面的 “支持“,“帮助”,“Integrations“。等菜单按钮,百试百灵,删除修改Help,Support菜单

♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ **ZABBIX修改web界面的 “支持”&#xff0c;“帮助”,“Integrations”。等菜单按钮&#xff0c…

基于 Transformer 的中文对联生成器

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

javaWeb学习04

AOP核心概念: 连接点: JoinPoint, 可以被AOP控制的方法 通知: Advice 指哪些重复的逻辑&#xff0c;也就是共性功能(最终体现为一个方法) 切入点: PointCut, 匹配连接点的条件&#xff0c;通知仅会在切入点方法执行时被应用 目标对象: Target, 通知所应用的对象 通知类…

模糊PID控制算法实战讲解-案例温度控制(附C语言实现)

可结合之前的文章一起理解&#xff1a; 控制算法-PID算法总结-从公式原理到参数整定解析&#xff08;附C源码&#xff09;_pid自整定算法-CSDN博客 模糊控制算法实战讲解-案例温度控制&#xff08;附C语言实现&#xff09;-CSDN博客 目录 一、模糊PID控制的原理 1.1 模糊化…

边读 Emacs Lisp Intro 边做题(五)

文章目录 边读Emacs Lisp Intro边做题&#xff08;五&#xff09; 边读Emacs Lisp Intro边做题&#xff08;五&#xff09; 打开emacs&#xff0c;按C-h i打开Info页&#xff0c;找到Emacs Lisp Intro。 这里的\\b\\([^ \n\t]\\)[ \n\t]\\1\\b抄自题目描述中提供的链接&#…

Decision Transformer

DT个人理解 emmm, 这里的Transformer 就和最近接触到的whisper一样,比起传统Transformer,自己还设计了针对特殊情况的tokens。比如whisper里对SOT,起始时间,语言种类等都指定了特殊tokens去做Decoder的输入和输出。 DT这里的作为输入的Tokens由RL里喜闻乐见的历史数据:…

Java优先级队列--堆

目录 1. 优先级队列 1.1 概念 2.优先级队列的模拟实现 2.1 堆的概念 2.2 堆的存储方式 2.3 堆的创建 2.3.1 堆向下调整 2.3.2 堆的创建 2.3.3 建堆的时间复杂度 2.4 堆的插入与删除 2.4.1 堆的插入 2.4.2 堆的删除 2.5 用堆模拟实现优先级队列 3.常用接口介绍 3…

Eigen-Block块操作

Block块操作 一、使用块操作二、列和行三、Corner-related操作四、向量的块运算 块是矩阵或数组的矩形部分。块表达式既可以用作右值&#xff0c;也可以用作左值。与通常的Eigen表达式一样&#xff0c;只要让编译器进行优化&#xff0c;这种抽象的运行时成本为零。优化都是自动…

什么是VR紧急情况模拟|消防应急虚拟展馆|VR游戏体验馆加盟

VR紧急情况模拟是利用虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术来模拟各种紧急情况和应急场景的训练和演练。通过VR技术&#xff0c;用户可以身临其境地体验各种紧急情况&#xff0c;如火灾、地震、交通事故等&#xff0c;以及应对这些紧急情况的…

贪心算法(算法竞赛、蓝桥杯)--修理牛棚

1、B站视频链接&#xff1a;A27 贪心算法 P1209 [USACO1.3] 修理牛棚_哔哩哔哩_bilibili 题目链接&#xff1a;[USACO1.3] 修理牛棚 Barn Repair - 洛谷 #include <bits/stdc.h> using namespace std; const int N205; int m,s,c,ans; int a[N];//牛的位置标号 int d[N…

奇怪的需求之与图片做交互

1.起因 客户想要展示自己的地图,该地图上有各种工作数据,和工作点位,已有的地图不能满足需求.于是提出将这张图片当成大背景 2.经过 鉴于文件格式和尺寸的原因,协商后客户提出将图片做成缩放效果,同时具有点击效果,原先直接进入的主页,现在为点击图片中的某条线路进入主页面…

Ubuntu tesseract使用全是干货

文字检测 方案 利用opencv二值化处理。最后检测使用google的开源库libtesseract识别文字。 tesseract安装 apt install libtesseract-dev # 前面那个是英文&#xff0c;后面那个是中文 apt install tesseract-oct tesseract-ocr-chi-sim手册 手册 qt creator中使用 pro文…

[LeetCode]143.重排链表

143. 重排链表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/reorder-list/description/ 题目 示例 解题思路 寻找链表中点 链表逆序 合并链表 注意到目标链表即为将原链表的左半端和反转后的右半端合并后的结果。 这样我们的任务即可划分为三步&a…

Redis 8种基本数据类型及常用命令和数据类型的应用场景

小伙伴们好&#xff0c;欢迎关注&#xff0c;一起学习&#xff0c;无限进步 文章内容为学习的一些笔记及工作中遇到的一些问题 文章目录 Redis 五大数据类型keyStringListSetHashSorted Set 三种特殊类型Geospatial 地理位置HyperloglogBitmap Redis 五大数据类型 redis 官方网…