handleOnPrepareScrollToIndex method

ObserverOnPrepareScrollToIndex? handleOnPrepareScrollToIndex({
  1. required GlobalKey<State<StatefulWidget>> nestedScrollViewKey,
  2. required NestedScrollUtilPosition position,
  3. required ScrollController outerScrollController,
  4. Duration? duration,
  5. Curve? curve,
  6. ObserverLocateIndexOffsetCallback? offset,
})

Handle the onPrepareScrollToIndex callback.

Implementation

ObserverOnPrepareScrollToIndex? handleOnPrepareScrollToIndex({
  required GlobalKey nestedScrollViewKey,
  required NestedScrollUtilPosition position,
  required ScrollController outerScrollController,
  Duration? duration,
  Curve? curve,
  ObserverLocateIndexOffsetCallback? offset,
}) {
  switch (position) {
    case NestedScrollUtilPosition.header:
      return null;
    case NestedScrollUtilPosition.body:
      return (calcResult) async {
        if (calcResult.calculateTargetLayoutOffset > 0) {
          // Here we can get the item's offset accurately.
          return false;
        }
        // The item is located relatively top, and the accurate item
        // offset cannot be obtained.
        // So here we jump through outerScrollController.
        final remainingSliverContext = fetchRemainingSliverContext(
          nestedScrollViewKey: nestedScrollViewKey,
        );
        var remainingSliverContextObj = ObserverUtils.findRenderObject(
          remainingSliverContext,
        );
        if (remainingSliverContextObj is! RenderSliverSingleBoxAdapter) {
          return false;
        }
        double targetOffset =
            remainingSliverContextObj.constraints.precedingScrollExtent;
        targetOffset -= offset?.call(targetOffset) ?? 0;
        targetOffset += calcResult.targetChildLayoutOffset;
        if (duration != null && curve != null) {
          await outerScrollController.animateTo(
            targetOffset,
            duration: duration,
            curve: curve,
          );
        } else {
          outerScrollController.jumpTo(targetOffset);
        }
        return true;
      };
  }
}