首页 > 其他分享 >Flutter进阶(4):定时器使用(Timer)

Flutter进阶(4):定时器使用(Timer)

时间:2024-11-15 16:00:45浏览次数:1  
标签:定时器 const 进阶 void Timer timer stopwatch Flutter

一、Timer简介

Flutter 的 Timer 类是 Dart 语言中的一个内置类,用于创建定时器。定时器可以用于在一段时间后执行代码,或者以固定的时间间隔重复执行代码。Timer 类提供了一种简单的方式来管理这些时间相关的任务。

二、Timer类的详细介绍

2.1 导入dart:async包

要使用 Timer 类,首先需要导入dart:async包,因为它包含了定时器相关的类和函数。

import 'dart:async';

2.2 创建一个定时器

使用 Timer 类的构造函数可以创建一个定时器。构造函数有两个参数,分别是持续时间(Duration)和回调函数(void Function())。

Timer(Duration duration, void Function() callback)
  • duration 参数表示定时器的持续时间,即多长时间后触发回调函数。
  • callback 参数是一个函数,它定义了当定时器触发时要执行的代码。

例如,以下代码创建一个在2秒后执行的定时器:

Timer(Duration(seconds: 2), () {
  print("定时器已触发");
});

2.3 取消定时器

你可以随时取消定时器,以防止回调函数执行。Timer 对象有一个cancel()方法,可以用来取消定时器。

Timer myTimer = Timer(Duration(seconds: 2), () {
  print("定时器已触发");
});

// 取消定时器
myTimer.cancel();

2.4 定时器的周期性执行

如果你想要定时器在固定的时间间隔内重复执行,可以使用periodic构造函数。它与 Timer 构造函数类似,但是会重复触发回调函数。

Timer.periodic(Duration(seconds: 2), (Timer timer) {
  print("定时器已触发");
});

在上面的例子中,回调函数每 2 秒执行一次。


2.5 注意事项

  • 定时器的回调函数会在一个隔离的事件循环中执行,不会阻塞主事件循环。
  • 定时器的精确性依赖于系统的可用性和负载,因此可能会有一些偏差。
  • 如果需要在主 UI 线程中执行操作,例如更新 UI,你需要确保使用setState()runOnUiThread()等机制。

三、计时器示例

下面使用 flutter 实现一个好看的计时器。先看下效果图:

Flutter_get_E.gif


main.dart 文件,代码如下:

import 'package:flutter/material.dart';
import 'dart:async';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});  
  @override
  Widget build(BuildContext context) => const MaterialApp(
      title: "My Stopwatch",
      home: StopwatchApp());
}

class StopwatchApp extends StatefulWidget {
  const StopwatchApp({super.key});
  @override
  State<StopwatchApp> createState() => _StopwatchAppState();
}

class _StopwatchAppState extends State<StopwatchApp> {
  String timeString = "00:00:00";
  Stopwatch stopwatch = Stopwatch();
  late Timer timer; // 定义定时器

  // 开始计时
  void start() {
    stopwatch.start();
    timer = Timer.periodic(const Duration(milliseconds: 100), update);
  }

  // 更新计时
  void update(Timer t) {
    if (stopwatch.isRunning) {
      setState(() {
        // 拼接时间字符串
        timeString =
            (stopwatch.elapsed.inMinutes % 60).toString().padLeft(2, "0") +
                ":" +
                (stopwatch.elapsed.inSeconds % 60).toString().padLeft(2,
                    "0") +
                ":" +
                (stopwatch.elapsed.inMilliseconds % 1000 / 10).clamp(0, 99)
                    .toStringAsFixed(0)
                    .padLeft(2, "0");
      });
    }
  }
  
  // 停止计时
  void stop() {
    setState(() {
      timer.cancel();
      stopwatch.stop();
    });
  }

  // 重置计时
  void reset() {
    timer.cancel();
    stopwatch.reset();
    setState(() {
      timeString = "00:00:00";
    });
    stopwatch.stop();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold (
        appBar: AppBar(
          title: const Text("My Stopwatch"),
        ),
        backgroundColor: Colors.blue,
        body: Column(
          children: <Widget> [
            Padding(padding: const EdgeInsets.symmetric(horizontal: 80,
                vertical: 60),
              child: Text("STOPWATCH",
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.grey.shade900,
                  )
              ),
            ),
            Expanded(
              child: Container(
                width: 250,
                height: 250,
                decoration: BoxDecoration(
                    color: Colors.pink,
                    shape: BoxShape.circle,
                    boxShadow: [
                      const BoxShadow(
                          offset: Offset(10,10),
                          color: Colors.red,
                          blurRadius: 5),
                      BoxShadow(
                          offset: const Offset(-10,-10),
                          color: Colors.white.withOpacity(0.85),
                          blurRadius: 5)
                    ]),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text('$timeString',
                        style: TextStyle(
                          fontSize: 40,
                          color: Colors.grey.shade900,
                        )
                    )
                  ],
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10, vertical:
              60),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  TextButton(
                      onPressed: reset,
                      child: Container(
                        height: 100,
                        width: 100,
                        decoration: const BoxDecoration(
                          color: Colors.white,
                          shape: BoxShape.circle,
                        ),
                        child: const Icon(Icons.refresh, size: 60),
                      )
                  ),
                  TextButton(
                    onPressed: () => {
                      stopwatch.isRunning ? stop() : start()
                    },
                    child: Container(
                      height: 100,
                      width: 100,
                      decoration: const BoxDecoration(
                        color: Colors.white,
                        shape: BoxShape.circle,
                      ),
                      child: Icon(stopwatch.isRunning ? Icons.pause :
                      Icons.play_arrow, size: 60),
                    ),
                  )
                ],
              ),
            )
          ],
        )
    );
  }
}

四、倒计时示例

如下图所示为常见 App 的一个启动页面的倒计时显示效果:

Flutter_get_F.gif


全部代码如下:

import 'package:flutter/material.dart';
import 'dart:async';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Timer"),
        ),
        body: const TimerDemo(),
      ),
    );
  }
}

class TimerDemo extends StatefulWidget {
  const TimerDemo({super.key});
  @override
  State<TimerDemo> createState() => _TimerDemoState();
}

class _TimerDemoState extends State<TimerDemo> {
  // 声明变量
  late Timer _timer;
  // 记录当前的时间
  int curentTimer = 0;

  @override
  void initState() {
    super.initState();

    // 循环执行
    // 间隔100ms
    _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
      // 自增
      curentTimer += 100;
      // 到5秒后重新计时
      if (curentTimer > 5000) {
        curentTimer = 0;
        //_timer.cancel();
      }
      setState(() {});
    });
  }

  @override
  void dispose() {
    // 取消计时器
    _timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("倒计时"),
      ),
      backgroundColor: Colors.white,

      // 填充布局
      body: Container(
          padding: const EdgeInsets.all(20),
          width: double.infinity,
          height: double.infinity,
          child: Column(
            children: [
              // 层叠布局将进度与文字叠在一起
              Stack(
                // 子Widget居中
                alignment: Alignment.center,
                children: [
                  // 圆形进度
                  CircularProgressIndicator(
                    // 当前指示的进度 0.0 -1.0
                    value: curentTimer / 5000,
                  ),
                  // 显示的文本
                  Text("${(curentTimer / 1000).toInt()}"),
                ],
              )
            ],
          )),
    );
  }
}

标签:定时器,const,进阶,void,Timer,timer,stopwatch,Flutter
From: https://www.cnblogs.com/linuxAndMcu/p/18548120

相关文章

  • C语言进阶3:字符串+内存函数
    本章重点求字符串长度strlen长度不受限制的字符串函数strcpystrcatstrcmp长度受限制的字符串函数strncpystrncatstrncmp字符串查找strstrstrtok误信息报告strerror字符操作内存操作memcpymemmovememcmpmemset0.前言:C语言中对字符和字符串的处理很是......
  • 指针(进阶)
    重点讲述:1.字符指针2.数组指针3.指针数组4.数组传参和指针传参5.函数指针6.函数指针数组7.指向函数指针数组的指针8.回调函数1.字符指针在指针的类型中我们知道有一种指针类型为字符指针char*一般使用:还有一种使用方式如下:代码constchar*pstr="zhuying.";有......
  • Python小白学习教程从入门到入坑------第三十二课 生成器(语法进阶)
    目录一、生成器generator1.1生成器表达式1.1.1表达式一1.1.2表达式二二、可迭代对象、迭代器、生成器三者之间的关系2.1定义与特性2.2关系与区别一、生成器generator在Python中,生成器(Generators)是一种用于迭代对象的特殊类型函数。它们允许你生成一个序列......
  • Python小白学习教程从入门到入坑------第三十一课 迭代器(语法进阶)
    目录一、可迭代对象Iterable1.1可迭代对象的条件1.2for循环工作原理1.3isinstance()二、迭代器 Iterator2.1 __iter__() 和 __next__()2.2 可迭代对象&迭代器2.2.1定义与特性2.2.2 关系与转换2.2.3应用场景三、迭代器协议(了解即可)四、自定义迭代器类......
  • Git进阶实用命令
    总结最常用的git命令操作。Mac推荐可视化软件Sourcetree1.本地仓库gitinit#初始化本地git以下所有操作的前提条件gitadd-A#添加当前所有变动文件到本地缓存区gitcommit-m'<commit-word>'#提交缓存区内容到本地仓库gitcommit-am'<commit-word>'#上......
  • Flutter插件Get(7):实现语言的国际化
    一、前言除了FlutterIntl的方式实现国际化(参考我以前的博客:Flutter进阶(2):国际化开发-fengMisaka-博客园),还可以使用GetX实现国际化(推荐)。先看下效果图:二、GetX实现国际化(推荐)新建一个Flutter工程,使用GetX实现国际化的具体步骤如下:2.1安装Getx在pubspec.yaml......
  • 分布式管理进阶:HarmonyOS Next 中的设备信息查询与状态监听
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在探索HarmonyOSNext的分布式管理服务时......
  • Chrome DevTools Protocol 进阶: Page域
    前言本章开始我们将进一步学习ChromeDevToolsProtocol(CDP),首先切入的内容是CDP中的域。在ChromeDevToolsProtocol(CDP)中,Page域是一个至关重要的部分,它负责控制浏览器页面的导航、加载、渲染以及其他与页面相关的操作。通过Page域,你可以执行页面跳转、截图、处理弹......
  • ArkUI进阶-1
    文章目录ArkUI(方舟UI框架)1.简介2.基本概念3.概述4.布局1.概述2.通用布局属性1.盒子属性2.背景属性3.定位属性4.通用属性3.线性布局(Row,Column)4.弹性布局(Flex)5.层叠布局(Stack)6.轮播(Swiper)......
  • 第三章:YashanDB 对象管理(进阶篇)
    YashanDB对象管理(进阶篇)表管理表是YashanDB中数据存储基本单元。每个表都是由列和行组成的。创建表时,需要指定表类型。表上可以有约束用于确保数据的有效性表的存储结构存储结构-Segment表——>表段索引——>索引段延迟段的创建USER_TABLESUSER_SEGMENTSR......