Flutter 抖动定时器问题

Flutter 抖动定时器问题,flutter,dart,time,timer,Flutter,Dart,Time,Timer,我实现了一个计时器,但它似乎没有在正确的持续时间后调用callback()函数,它在几秒钟后开始调用回调函数,并在每次调用回调时加速。 例如,5秒-->回调()、4秒-->回调()、2-->回调()、0.3秒-->回调() 我想有一个计时器,每秒钟减少一个int的值 当前代码-视图模型: void displayCountdown(Item item) { timer = Timer.periodic(const Duration(seconds: 1), (Timer _timer

我实现了一个计时器,但它似乎没有在正确的持续时间后调用callback()函数,它在几秒钟后开始调用回调函数,并在每次调用回调时加速。 例如,5秒-->回调()、4秒-->回调()、2-->回调()、0.3秒-->回调()

我想有一个计时器,每秒钟减少一个int的值

当前代码-视图模型:

  void displayCountdown(Item item) {
    timer = Timer.periodic(const Duration(seconds: 1), (Timer _timer) => {
      if (lead.remainingTime >= 1) {
        item.remainingTime = item.remainingTime -= 1,
        notifyListeners(),
      }else {
        print('out of time'),
        _timer.cancel(),
        notifyListeners(),
      }
    });
  }
代码-视图:

  ListTile _tile(Item item) {
    widget.model.displayCountdown(item);
    Duration duration = Duration(milliseconds: item.remainingTime);
    String countdown = '${duration.toString().split('.')[0]}';
    return ListTile(
      leading: CircleAvatar(
        backgroundImage: item.author["avatarUrl"] == "" ? NetworkImage('https://picsum.photos/250?image=3') : NetworkImage(lead.author["avatarUrl"]),
      ),
      title: Text(item.author["fullName"]),
      subtitle: Text(item.keywords.toString()),
      trailing: Row(mainAxisSize: MainAxisSize.min, children: [Text('$countdown', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.grey))],),
    );
  }

我不知道为什么它不起作用,但我找到了一个可行的替代方案

首先,我为我的倒计时创建一个getter。 第二,当我得到我的物品时,我在getter中设置每个计时器。 第三,我用getter值创建计时器。 第四,我在视图中当前磁贴的索引处调用getter

...
  List<int> get countDowns => _durations;
  List<int> _durations = [];

  List<Item> items = [];
...

  Future getItems() async {
    setState(ViewState.Busy);
    final response = await _api.getItems();
    if (response is SuccessState) {
      items = response.value;
      for (var item in items) {
        _durations.add(item.remainingTime);
      }
      displayCountdowns();
    } else if (response is ErrorState) {
      String error = response.msg;
      print('Error $error');
    } else {
      print('Error');
    }
    setState(ViewState.Idle);
  }
...
  void displayCountdowns() {
    for (var countDown in _durations) {
      Timer.periodic(const Duration(seconds: 1), (timer) { 
        countDown -= 1000;
        _durations[0] = countDown;
        notifyListeners();
      });
    }
  }

“它从几秒钟后调用回调开始,每次调用回调时都会加速”。。。您确定没有为同一
项目创建多个
计时器吗?不,我不这么认为。我还不太习惯飞。也许每次我调用
widget.model.displayCountdown(lead)时,它都会创建一个新的并因此加速它?我创建计时器的唯一位置是displayCountdown()。是的,每次调用
小部件.model.displayCountdown()
,它都会创建一个新的定期
计时器
对象。它不会影响现有的
计时器,但您将有比预期更多的运行时间,因此您将观察到更多的回调被触发。如果您打算为每个
项目
设置一个
计时器
,我建议您维护一个
映射
,这样您就可以避免在已有计时器的情况下创建新的
计时器(或取消现有计时器)。谢谢,但我找到了另一个x)。
...
var duration = Duration(milliseconds:widget.model.countDowns[index]);
...
  ListTile _tile(Lead lead, Duration duration) {
    String countdown = '${duration.toString().split('.')[0]}';
    return ListTile(
      leading: CircleAvatar(
        backgroundImage: lead.author["avatarUrl"] == "" ? NetworkImage('https://picsum.photos/250?image=3') : NetworkImage(lead.author["avatarUrl"]),
      ),
      title: leadTitle(lead.author["fullName"]),
      subtitle: leadSubtitle(lead.keywords.toString()),
      trailing: Row(mainAxisSize: MainAxisSize.min, children: [Text('$countdown', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.grey))],),
    );
  }