flutter - 如何在 Flutter 中使用可变持续时间的计时器

如何使计时器的速度每分钟增加一次,即计时器持续时间在 Flutter 中每 1 分钟减少一次?

回答1

正如评论部分所说,您可以使用递归函数来完成工作。

import 'dart:async';

void main() {
  launchTimer(Duration(seconds: 2), minDuration: Duration(milliseconds: 300));
}

void launchTimer(Duration duration, {Duration? minDuration}) =>   Timer(duration, () {
    final wantedDuration = duration - Duration(milliseconds: 300);
  
    if (minDuration != null && wantedDuration < minDuration) {
      print('minDuration');
      launchTimer(minDuration, minDuration: minDuration);
    } else {
      print('wantedDuration');
      launchTimer(wantedDuration, minDuration: minDuration);
    }
});

在这个例子中,我有一个 minDuration 限制,以避免不必要的行为。

您可以将此代码导入到 dart 垫中尝试一下:)

回答2

这是一个 Timer 实现,它的作用类似于普通的周期性 Timer 但允许回调修改周期(甚至回调):

import 'dart:async';

class VariableTimer implements Timer {
  void Function(VariableTimer) callback;
  Duration period;
  Timer? _timer;
  int _tick = 0;

  VariableTimer(Duration initialPeriod, this.callback)
      : period = initialPeriod {
    _timer = Timer(initialPeriod, _onTimer);
  }

  @override
  bool get isActive => _timer != null;

  @override
  int get tick => _tick;

  @override
  void cancel() {
    _timer?.cancel();
    _timer = null;
  }

  void _onTimer() {
    var stopwatch = Stopwatch()..start();
    _tick += 1;
    callback(this);
    if (!isActive) {
      return;
    }

    var adjustedPeriod = _max(Duration.zero, period - stopwatch.elapsed);
    _timer = Timer(adjustedPeriod, _onTimer);
  }
}

Duration _max(Duration duration1, Duration duration2) =>
    duration1 >= duration2 ? duration1 : duration2;

创建周期性 Timer 的示例用法,最初每 10 秒触发一次,每分钟触发一秒,当周期达到 0 时停止:

void main() {
  const oneMinute = Duration(minutes: 1);
  var nextUpdate = DateTime.now().add(oneMinute);
  VariableTimer(const Duration(seconds: 10), (timer) {
    print(DateTime.now());
    
    var timeToNext = nextUpdate.difference(DateTime.now());
    if (timeToNext <= Duration.zero) {
      nextUpdate = nextUpdate.add(oneMinute);

      timer.period -= const Duration(seconds: 1);
      if (timer.period <= Duration.zero) {
        timer.cancel();
      }
    }
  });
}

相似文章

随机推荐

最新文章