【问题标题】:Flutter Timer Issue颤振计时器问题
【发布时间】:2020-10-15 12:14:14
【问题描述】:

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

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

当前代码 - ViewModel:

  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))],),
    );
  }

【问题讨论】:

  • “它从几秒钟后调用回调开始,每次调用回调时都会加快速度” ...您确定您没有为同一个@创建多个Timers 987654324@s?
  • 不,我不这么认为。我还不太习惯颤抖。也许每次我调用widget.model.displayCountdown(lead); 时它都会创建一个新的,因此它会加速它?我创建 Timer 的唯一地方是 displayCountdown()。
  • 是的,每次调用widget.model.displayCountdown(),都会创建一个新的周期性@​​987654327@对象。它不会影响现有的Timers,但是您的运行次数会比您预期的要多,因此您会观察到更多的回调被触发。如果您的意图是每个Item 有一个Timer,我建议您维护一个Map<Item, Timer>,这样您就可以避免创建一个新的Timer(如果已经存在)(或者这样您就可以取消现有的)。
  • 谢谢,但我找到了替代 x)。

标签: flutter dart time timer


【解决方案1】:

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

首先,我为我的倒计时创建了一个吸气剂。 其次,当我拿到我的物品时,我会在我的 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();
      });
    }
  }

这是视图的代码:

...
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))],),
    );
  }

【讨论】:

    猜你喜欢
    • 2021-05-17
    • 2019-07-03
    • 2021-11-16
    • 2021-05-05
    • 2022-01-12
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多