Flutter ListView controller.animateTo 无效

在使用Flutter自定义一个滚轮组件时,当监听到滚动停止后,再控制ListView滚动几个像素达到完美效果,按照正常流程完成这个逻辑如下

  bool notificationFunction(Notification notification) {
    switch (notification.runtimeType) {
      case ScrollStartNotification:
        break;
      case ScrollUpdateNotification:
        break;
      case ScrollEndNotification:
        double offset = controller.offset;
        int currentIndex = ItemPainter.calculateCenterIndex(
            offset, widget.scrollDirection, list.length, widget.itemSize, parentSize ?? Size.zero);
        bool vertical = widget.scrollDirection == Axis.vertical;
        double diff = 0;
        if (vertical) {
          double top = currentIndex * widget.itemSize.height - offset;
          double center = top + widget.itemSize.height / 2;
          diff = (center - parentSize!.height / 2.0);
        } else {
          double left = currentIndex * widget.itemSize.width - offset;
          double center = left + widget.itemSize.width / 2;
          diff = (center - parentSize!.width / 2.0);
        }
        controller.animateTo(offset + diff, duration: const Duration(milliseconds: 200), curve: Curves.linear);

        break;
      case OverscrollNotification:
        break;
    }
    return false;
  }

上面的逻辑就是判断滚动偏差,然后手动滚动到正确位置,一切看起来都是没毛病。

在真机或者模拟器上面调试发现controller.animateTo 不起作用。

最后才发现这是Flutter 的一个坑,坑,坑。

在监听到ScrollEndNotification,停止滚动时无法立即调用controller.animateTo,正确调用方法为

        Future.delayed(Duration.zero, () {
          controller.animateTo(offset + diff, duration: const Duration(milliseconds: 200), curve: Curves.linear);
        });

必需用Fluter.dalayed 包装起来,等到下一个event loop 才能执行。

希望对你学习Flutter有所帮组

你可能感兴趣的:(flutter)