Flutter定时器控制插件timer_controller的使用

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

Flutter定时器控制插件timer_controller的使用

概述

timer_controller 是一个Flutter库,它提供了对计时器的操作(播放、暂停、重启等)以及用于消费计时器值的小部件。这个库非常适合需要在应用中实现倒计时或正计时功能的开发者。

开始使用

添加依赖

在你的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  ...
  timer_controller: ^0.1.0

然后在 Dart 文件中导入包:

import 'package:timer_controller/timer_controller.dart';

TimerController

TimerController 继承自 ValueNotifier,因此你可以访问它的 value 属性来获取计时器的信息。

构造函数

根据可用的时间单位,可以使用不同的构造函数创建 TimerController 实例:

final TimerController secondsTimer = TimerController.seconds(15);
final TimerController minutesTimer = TimerController.minutes(3);
final TimerController hoursTimer = TimerController.hours(2);

注意:记得在不再需要 TimerController 时调用 dispose() 方法释放资源。

控制方法

  • start():开始计时。
  • pause():暂停计时。
  • reset():将计时器重置为初始值。
  • restart():将计时器重置为初始值并重新开始计时。

TimerValue

TimerValue 表示计时器的状态,并具有以下属性:

TimerValue({
  required int remaining, // 剩余时间
  required TimerUnit unit, // 计时单位
  TimerStatus status = TimerStatus.initial, // 计时器状态
});

内置小部件

timer_controller 提供了几个内置的小部件来构建基于控制器的UI或执行某些动作。

TimerControllerBuilder

TimerControllerBuilder 可以根据 TimerController 的值构建小部件:

TimerControllerBuilder(
  controller: myTimerController,
  builder: (context, value, child) {
    // 根据 myTimerController 的值返回相应的 widget
  }
)

可选条件:如果想要更细粒度地控制何时调用构建函数,可以提供一个条件给 TimerControllerBuilder。该条件接受前一个计时器值和当前计时器值作为参数,并返回一个布尔值。如果条件返回 true,则构建函数将被调用,并且小部件会重新构建;如果条件返回 false,则不会调用构建函数也不会触发重建。

TimerControllerListener

TimerControllerListener 可以根据 TimerController 的值运行特定的动作:

TimerControllerListener(
  controller: myTimerController,
  listener: (context, value) {
    // 根据 myTimerController 的值执行相应操作
  },
  child: Container(),
)

可选条件:与 TimerControllerBuilder 类似,可以通过提供条件来控制监听器函数的调用时机。

示例代码

下面是一个完整的示例程序,展示了如何使用 timer_controller 创建一个简单的计时器应用程序:

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Timer controller demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const _TimerWidget(),
    );
  }
}

class _TimerWidget extends StatefulWidget {
  const _TimerWidget({Key? key}) : super(key: key);

  @override
  __TimerWidgetState createState() => __TimerWidgetState();
}

class __TimerWidgetState extends State<_TimerWidget> {
  late TimerController _controller;

  @override
  void initState() {
    _controller = TimerController.seconds(20);
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Timer controller demo'),
      ),
      body: TimerControllerListener(
        controller: _controller,
        listenWhen: (previousValue, currentValue) =>
            previousValue.status != currentValue.status,
        listener: (context, timerValue) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text('Status: ${describeEnum(timerValue.status)}'),
              duration: const Duration(seconds: 1),
            ),
          );
        },
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TimerControllerBuilder(
                controller: _controller,
                builder: (context, timerValue, _) {
                  Color timerColor = Colors.black;
                  switch (timerValue.status) {
                    case TimerStatus.initial:
                      timerColor = Colors.black;
                      break;
                    case TimerStatus.running:
                      timerColor = Colors.green;
                      break;
                    case TimerStatus.paused:
                      timerColor = Colors.grey;
                      break;
                    case TimerStatus.finished:
                      timerColor = Colors.red;
                      break;
                  }
                  return Text(
                    '${timerValue.remaining}',
                    style: TextStyle(
                      fontSize: 50,
                      color: timerColor,
                    ),
                  );
                },
              ),
              const SizedBox(height: 40),
              Wrap(
                spacing: 20,
                runSpacing: 20,
                children: [
                  _ActionButton(
                    title: 'Start',
                    onPressed: () => _controller.start(),
                  ),
                  _ActionButton(
                    title: 'Pause',
                    onPressed: () => _controller.pause(),
                  ),
                  _ActionButton(
                    title: 'Reset',
                    onPressed: () => _controller.reset(),
                  ),
                  _ActionButton(
                    title: 'Restart',
                    onPressed: () => _controller.restart(),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _ActionButton extends StatelessWidget {
  const _ActionButton({
    Key? key,
    this.onPressed,
    required this.title,
  })  : assert(title != null),
        super(key: key);

  final VoidCallback? onPressed;
  final String title;

  @override
  Widget build(BuildContext context) {
    return OutlinedButton(
      onPressed: onPressed,
      child: Text(title),
    );
  }
}

这段代码创建了一个包含计时器显示和四个按钮(开始、暂停、重置、重启)的应用程序界面。当计时器状态改变时,还会显示一个短暂的消息提示用户当前的状态。


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

1 回复

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


当然,以下是一个关于如何在Flutter中使用timer_controller插件来控制定时器的代码示例。timer_controller是一个假定的插件名称,因为实际上Flutter生态系统中没有一个广泛认可的名为timer_controller的插件。不过,我们可以模拟一个类似的定时器控制逻辑,通常可以通过TickerProviderStateMixinAnimationController来实现类似的功能。

为了演示,我们将创建一个简单的Flutter应用,其中包含一个按钮,点击按钮后开始一个定时器,并在屏幕上显示经过的时间。我们还将提供一个停止按钮来停止定时器。

首先,确保你的pubspec.yaml文件中包含了必要的依赖项(虽然本例不直接依赖外部插件,但Flutter开发通常需要flutter依赖):

dependencies:
  flutter:
    sdk: flutter

接下来,在你的main.dart文件中编写以下代码:

import 'package:flutter/material.dart';

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

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

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

class _TimerScreenState extends State<TimerScreen> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<int> _animation;
  int _elapsedTime = 0;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(days: 1), // Long duration to simulate indefinite running
      vsync: this,
    )..repeat(reverse: false); // We won't actually use the animation's value for timing

    // Create an animation that updates every second (or any desired interval)
    _animation = IntTween(begin: 0, end: _controller.value.toInt() * 1000) // Dummy end value
        .animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.linear,
    ))
      ..addListener(() {
        setState(() {
          // Here we manually update the elapsed time (not using _animation.value directly)
          _elapsedTime = DateTime.now().difference(_startTime).inSeconds;
        });
      });

    // Start time for elapsed time calculation
    DateTime _startTime = DateTime.now();

    // We will use a Timer to update our state instead of relying on _animation.value
    Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        _elapsedTime = DateTime.now().difference(_startTime).inSeconds;
      });
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _startTimer() {
    // In this demo, the timer starts immediately in initState, so this function is a no-op.
    // You can modify this to reset and restart the timer if needed.
  }

  void _stopTimer() {
    _controller.stop();
    // Optionally, you can reset the timer here if needed: _controller.reset();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Timer Controller Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Elapsed Time: $_elapsedTime seconds',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _startTimer, // In this demo, just a placeholder
              child: Text('Start Timer'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: _stopTimer,
              child: Text('Stop Timer'),
            ),
          ],
        ),
      ),
    );
  }
}

注意

  1. 在这个示例中,我们实际上并没有直接使用AnimationController来控制定时器的显示(因为我们手动计算了经过的时间),但展示了如何结合TickerProviderStateMixinAnimationController的初始化流程。
  2. 为了模拟定时器的功能,我们使用了一个Timer.periodic来每秒更新一次UI。
  3. _startTimer函数在这个示例中没有实际作用,因为定时器在initState中就已经开始。你可以根据需求修改这部分逻辑,比如重置和重新开始定时器。
  4. 停止定时器时,我们调用了_controller.stop(),但实际上并没有用到_controller的动画值。在实际应用中,你可能需要根据具体需求调整这部分逻辑。

这个示例提供了一个基础框架,你可以根据自己的需求进一步扩展和优化。

回到顶部