google / flutter.widgets

Home Page:https://pub.dev/packages/flutter_widgets

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

_ScrollablePositionedListState._scrollTo has a mistake.

darkstarx opened this issue · comments

if _isTransitioning, it returns immediately and the client code triggers immediately as well 'cause there's no any Future to wait for to know when the scrolling completes. That is a bug.
You must use Completer to notify the client code about finishing the asynchronous scrolling initiated in the post-frame callback.

  Future<void> _scrollTo({
    required int index,
    required double alignment,
    required Duration duration,
    Curve curve = Curves.linear,
    required List<double> opacityAnimationWeights,
  }) async {
    if (index > widget.itemCount - 1) {
      index = widget.itemCount - 1;
    }
    if (_isTransitioning) {
      _stopScroll(canceled: true);
      // HERE we must wait until the internal call to  _startScroll completes!!!
      SchedulerBinding.instance.addPostFrameCallback((_) {
        _startScroll(
          index: index,
          alignment: alignment,
          duration: duration,
          curve: curve,
          opacityAnimationWeights: opacityAnimationWeights,
        );
      });
    } else {
      await _startScroll(
        index: index,
        alignment: alignment,
        duration: duration,
        curve: curve,
        opacityAnimationWeights: opacityAnimationWeights,
      );
    }
  }

So I think the problem shows up when the client calling here waits on the returned future as an indicator that the scrolling is done, but currently the future resolves potentially before the scrolling finishes. Let me see if I can fix that without adding other problems.