Flutter计时器功能插件timer_flutter的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter计时器功能插件timer_flutter的使用

timer_flutter 是一个功能强大且易于使用的 Flutter 包,用于创建和管理基于当前 DateTime 的计时器。它支持多监听器同步当前时间、毫秒级更新、进度跟踪(0到1)、格式化时间输出、计时器状态监控、圆形进度条和饼状图等特性。此外,还支持倒计时和剩余时间的显示。

功能展示

以下是一些示例图片展示了 timer_flutter 的不同使用方式:

计时器监听器

timer_flutter 提供了多种监听器来跟踪计时器的状态和进度:

  • statusListener: 监听计时器状态,包括 notStartedYetstartedendedresetclear
  • timeListener: 监听格式化的时间,例如 HH:MM:SS:ms
  • millisecondsListener: 监听以毫秒为单位的计时器值。
  • progress0to1Listener: 监听计时器进度,范围从 01

计时器控制器

timer_flutter 使用 TimerFController 来控制计时器的各种操作:

late TimerFController _timerFController;

_timerFController = TimerFController(
    startTime: DateTime.now().add(
        const Duration(seconds: 18)), // 计时器将在18秒后开始
    duration: const Duration(minutes: 8),
    timeFormate: "MM:SS:ms",
    listeningDelay: const Duration(milliseconds: 50),
    statusListener: (status) {
    log("timer: --status: $status");
    },
    isCountdown: true,
    millisecondsListener: (pms) {
    log("timer: --ms: $pms");
    },
    progress0to1Listener: (progress) {
    log("timer: --progress: $progress");
    },
    timeListener: (value) {
    log("timer: --time: $value");
    },
);

控制器方法

  • controller.reset(): 重置计时器。
  • controller.pause(): 暂停计时器。
  • controller.resume(): 恢复计时器。
  • controller.clear(): 清除计时器。
  • controller.dispose(): 释放资源。
  • controller.controller.stream: 使用 StreamBuilder 监听格式化的时间。
StreamBuilder<String>(
    stream: _timerFController.controller.stream,
    builder: (context, snapshot) {
        if (snapshot.hasData) {
        return Text(snapshot.data ?? '',
            style: const TextStyle(color: Colors.black));
        } else {
        return const Text("not started",
            style: TextStyle(color: Colors.black));
        }
    }
),

获取时间过去/剩余

timer_flutter 还提供了获取时间过去和剩余的功能:

时间过去

final DateTime pastDateTime = DateTime.parse('2024-08-27 23:31:15.000');
String timeagoStr = TimeF.timeAgo(pastDateTime, formate: TimeAgoFormate(second: "## sec'# ago", week: "## week'# ago"), 
  listenerDateTimeF: (dtf) {
    log(" Ago DateTimeF Listener: ${dtf.toString()}"); // Ago DateTimeF Listener: DateTimeF(year: 0, month: 2, week: 3, day: 3, hour: 1, minute: 1, second: 10)
  });

log(timeagoStr); // 2 months ago

剩余时间

final DateTime futureDateTime = DateTime.parse('2024-11-26 23:31:15.000');
String timeExpireStr = TimeF.timeLeft(futureDateTime, formate: TimeLeftFormate(hour: "Offer expire in ## hour'#", day: "Offer expire in ## day'#"), 
  listenerDateTimeF: (dtf) {
    log("Left DateTimeF Listener: ${dtf.toString()}"); // Left DateTimeF Listener: DateTimeF(year: 0, month: 0, week: 0, day: 6, hour: 22, minute: 58, second: 49)
  });

log(timeExpireStr); // Offer expire in 6 days

圆形进度条和饼状图类型的计时器小部件构建

timer_flutter 还提供了圆形进度条和饼状图类型的计时器小部件构建功能:

FlutterCircularProgressTimer(
  isPieShape: false,
  timerControllerValues: TimerControllerValues(
      listeningDelay: const Duration(milliseconds: 100),
      timeFormate: "MM:SS",
      isCountdown: true,
      duration: const Duration(minutes: 5),
      statusListener: (status) {
        log("Timer status: $status");
      },
      controller: (controller) {
        timerFController = controller;
      }),
  radius: 60,
  decoraton: CircularTimerDecoraton(
    fillColor: Colors.transparent,
    progressBackgroundColor: Colors.grey.withAlpha((255.0 * 0.2).round()),
    prgressThickness: 12,
    progressMaskFilter:
        const MaskFilter.blur(BlurStyle.inner, 11.5),
    progressColors: const [Colors.blue],
    // progressShadow: ProgressShadow(
    //     color: Colors.red, opacity: 0.5, blur: 9.8, spreadRadius: 18),
  ),
  builder: (BuildContext context, value, progress) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(
          value ?? '',
          style: const TextStyle(
            fontSize: 38,
            color: Colors.black,
            fontWeight: FontWeight.w300,
          ),
        ),
        const Text(
          "minutes",
          style: TextStyle(
            fontSize: 14,
            color: Colors.black,
            fontWeight: FontWeight.w800,
          ),
        ),
      ],
    );
  },
),

完整示例代码

以下是完整的示例代码,展示了如何在 Flutter 应用程序中使用 timer_flutter 插件:

import 'dart:log';

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Timer Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const TimerFlutterDemo(),
    );
  }
}

class TimerFlutterDemo extends StatefulWidget {
  const TimerFlutterDemo({super.key});

  [@override](/user/override)
  State<TimerFlutterDemo> createState() => _TimerFlutterDemoState();
}

class _TimerFlutterDemoState extends State<TimerFlutterDemo> {
  late TimerFController timerFController;
  late TimerFController timerFController2;

  late AppLifecycleListener _appLifecycleListener;

  [@override](/user/override)
  void initState() {
    super.initState();
    timerFController2 = TimerFController(
        timeFormate: "HH:MM:SS:ms",
        duration: const Duration(hours: 18),
        progress0to1Listener: (p) {
          log("progress0to1Listener: $p");
        });

    _appLifecycleListener = AppLifecycleListener(onStateChange: (state) {
      if (state == AppLifecycleState.paused) {
        timerFController2.pause();
      }
      if (state == AppLifecycleState.resumed) {
        timerFController2.resume();
      }
    });
  }

  [@override](/user/override)
  void dispose() {
    timerFController.dispose();
    timerFController2.dispose();
    _appLifecycleListener.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    StreamBuilder(
                      stream: timerFController2.controller.stream,
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          return Text(snapshot.data ?? '',
                              style: const TextStyle(
                                  color: Colors.black, fontSize: 18));
                        } else {
                          return const Text("not started",
                              style: TextStyle(color: Colors.black));
                        }
                      },
                    ),
                    const SizedBox(height: 18),
                    Row(
                      spacing: 8,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        ElevatedButton(
                          onPressed: () {
                            timerFController2.reset();
                          },
                          child: const Text("reset"),
                        ),
                        ElevatedButton(
                          onPressed: () {
                            timerFController2.pause();
                          },
                          child: const Text("pause"),
                        ),
                        ElevatedButton(
                          onPressed: () {
                            timerFController2.resume();
                          },
                          child: const Text("resume"),
                        ),
                      ],
                    ),
                  ],
                ),
                const Divider(height: 90),
                FlutterCircularProgressTimer(
                  isPieShape: false,
                  timerControllerValues: TimerControllerValues(
                      listeningDelay: const Duration(milliseconds: 100),
                      timeFormate: "MM:SS",
                      isCountdown: true,
                      duration: const Duration(minutes: 5),
                      statusListener: (status) {
                        log("Timer status: $status");
                      },
                      controller: (controller) {
                        timerFController = controller;
                      }),
                  radius: 60,
                  decoraton: CircularTimerDecoraton(
                    fillColor: Colors.transparent,
                    progressBackgroundColor:
                        Colors.grey.withAlpha((255.0 * 0.2).round()),
                    prgressThickness: 12,
                    progressMaskFilter:
                        const MaskFilter.blur(BlurStyle.inner, 11.5),
                    progressColors: const [Colors.blue],
                    // progressShadow: ProgressShadow(
                    //     color: Colors.red, opacity: 0.5, blur: 9.8, spreadRadius: 18),
                  ),
                  builder: (BuildContext context, value, progress) {
                    return Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(
                          value ?? '',
                          style: const TextStyle(
                            fontSize: 38,
                            color: Colors.black,
                            fontWeight: FontWeight.w300,
                          ),
                        ),
                        const Text(
                          "minutes",
                          style: TextStyle(
                            fontSize: 14,
                            color: Colors.black,
                            fontWeight: FontWeight.w800,
                          ),
                        ),
                      ],
                    );
                  },
                ),
                const SizedBox(height: 18),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  spacing: 8,
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        timerFController.reset();
                      },
                      child: const Text("reset"),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        timerFController.pause();
                      },
                      child: const Text("pause"),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        timerFController.resume();
                      },
                      child: const Text("resume"),
                    ),
                  ],
                ),

                const Divider(height: 90),

                /// --Time Ago
                Text(
                  _getTimeAgo(),
                  style: const TextStyle(color: Colors.black, fontSize: 18),
                ),

                /// --Time Left
                Text(
                  _getTimeLeft(),
                  style: const TextStyle(color: Colors.black, fontSize: 18),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  String _getTimeAgo() {
    final DateTime pastDateTime =
        DateTime.now().subtract(const Duration(minutes: 1890));
    String timeagoStr = TimeF.timeAgo(pastDateTime,
        formate: TimeAgoFormate(second: "## sec'# ago", week: "## week'# ago"),
        listenerDateTimeF: (dtf) {
      log(" Ago DateTimeF Listener: ${dtf.toString()}"); // Ago DateTimeF Listener: DateTimeF(year: 0, month: 2, week: 3, day: 3, hour: 1, minute: 1, second: 10)
    });
    return timeagoStr;
  }

  String _getTimeLeft() {
    final DateTime pastDateTime = DateTime.now().add(const Duration(days: 18));
    String timeagoStr = TimeF.timeLeft(pastDateTime,
        formate: TimeLeftFormate(
            second: "expire in ## sec'#",
            week: "expire in ## week'#",
            day: "expire in ## day'#"), listenerDateTimeF: (dtf) {
      log(" Ago DateTimeF Listener: ${dtf.toString()}"); // Ago DateTimeF Listener: DateTimeF(year: 0, month: 2, week: 3, day: 3, hour: 1, minute: 1, second: 10)
    });
    return timeagoStr;
  }
}

更多关于Flutter计时器功能插件timer_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter计时器功能插件timer_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用timer_flutter插件来实现一个简单计时器功能的示例代码。假设你已经通过pubspec.yaml文件添加了timer_flutter依赖并运行了flutter pub get来安装该插件。

1. 添加依赖

首先,确保你的pubspec.yaml文件中包含以下依赖:

dependencies:
  flutter:
    sdk: flutter
  timer_flutter: ^x.y.z  # 请使用最新版本号替换 x.y.z

2. 导入插件

在你的Dart文件中(例如main.dart),导入timer_flutter插件:

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

3. 创建计时器功能

下面是一个完整的Flutter应用示例,它包含一个按钮来启动和停止计时器,并在屏幕上显示经过的时间:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Timer Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: TimerScreen(),
    );
  }
}

class TimerScreen extends StatefulWidget {
  @override
  _TimerScreenState createState() => _TimerScreenState();
}

class _TimerScreenState extends State<TimerScreen> with TickerProviderStateMixin {
  late TimerController _timerController;
  late AnimationController _animationController;
  late Animation<int> _animation;
  String _elapsedTime = '00:00:00';
  bool _isRunning = false;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      duration: const Duration(hours: 0, minutes: 0, seconds: 0, milliseconds: 1),
      vsync: this,
    )..repeat(reverse: true);

    _timerController = TimerController(
      initialDuration: const Duration(hours: 0, minutes: 0, seconds: 0),
      onTick: (duration) {
        setState(() {
          _elapsedTime = duration.toString().split('.')[0];
        });
      },
      onFinish: () {
        setState(() {
          _isRunning = false;
          _elapsedTime = '00:00:00';
        });
      },
    );

    _animation = IntTween(
      begin: 0,
      end: 1,
    ).animate(_animationController);
  }

  @override
  void dispose() {
    _timerController.dispose();
    _animationController.dispose();
    super.dispose();
  }

  void _toggleTimer() {
    setState(() {
      if (_isRunning) {
        _timerController.pause();
      } else {
        _timerController.resume();
      }
      _isRunning = !_isRunning;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Timer Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              _elapsedTime,
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _toggleTimer,
              child: Text(_isRunning ? 'Pause' : 'Start'),
            ),
          ],
        ),
      ),
    );
  }
}

4. 运行应用

确保你已经正确配置了Flutter开发环境,然后运行应用:

flutter run

解释

  • TimerControllertimer_flutter 插件提供的类,用于管理计时器的开始、暂停和停止。
  • onTick 回调在计时器每次更新时被调用,这里我们用它来更新显示的时间。
  • onFinish 回调在计时器结束时被调用,这里我们用它来重置状态。
  • TickerProviderStateMixin 允许我们使用 AnimationController
  • _animationController_animation 在这个示例中未直接使用,但可以作为未来添加动画效果的基础。

这个示例展示了如何使用timer_flutter插件来实现一个简单的计时器功能,包括启动、暂停和显示经过的时间。你可以根据需要进一步扩展和定制此功能。

回到顶部