updateScrollIndicator method

  1. @override
void updateScrollIndicator(
  1. double? page,
  2. List<Size>? sizeList,
  3. ValueNotifier<ScrollProgress> scroller,
  4. ValueNotifier<IndicatorPosition> notifier,
)
override

Implementation

@override
void updateScrollIndicator(
  double? page,
  List<Size>? sizeList,
  ValueNotifier<ScrollProgress> scroller,
  ValueNotifier<IndicatorPosition> notifier,
) {
  ScrollTabItem info = controller.computeScrollTabItem(page!, sizeList!);
  Size size = info.nextItemSize;
  bool isLast = info.isLast;

  if (size.width == -1 && size.height == -1 && !isLast) {
    return;
  }

  double totalTabbarWidth = info.totalTabBarSize.width;
  double tabBarViewHeight = info.totalTabBarSize.height;

  // currentOffsetX/Y -> end of itemSize
  double currentOffsetX = info.currentEndOffset.dx;
  double currentOffsetY = info.currentEndOffset.dy;
  double currentHeight = info.currentItemSize.height;
  double currentWidth = info.currentItemSize.width;
  double currentIndicatorHeight = currentHeight;
  double currentIndicatorWidth = currentWidth;

  double nextHeight = info.nextItemSize.height;
  double nextWidth = info.nextItemSize.width;
  double nextIndicatorHeight = nextHeight;
  double nextIndicatorWidth = nextWidth;

  double indicatorHeight = currentHeight;
  double indicatorWidth = currentWidth;

  if (width != null) {
    // when width < 0, set relative value
    nextIndicatorWidth = min(
      min(
        nextWidth + width!,
        nextWidth,
      ),
      width! <= 0 ? double.infinity : width!,
    );

    currentIndicatorWidth = min(
      min(
        currentWidth + width!,
        currentWidth,
      ),
      width! <= 0 ? double.infinity : width!,
    );
  }

  if (height != null) {
    // when height < 0, set relative value
    nextIndicatorHeight = min(
      min(
        nextHeight + height!,
        nextHeight,
      ),
      height! <= 0 ? double.infinity : height!,
    );

    currentIndicatorHeight = min(
      min(
        currentHeight + height!,
        currentHeight,
      ),
      height! <= 0 ? double.infinity : height!,
    );
  }

  if (nextIndicatorWidth < 0) nextIndicatorWidth = 0;
  if (nextIndicatorHeight < 0) nextIndicatorHeight = 0;
  if (currentIndicatorWidth < 0) currentIndicatorWidth = 0;
  if (currentIndicatorHeight < 0) currentIndicatorHeight = 0;

  indicatorWidth = currentIndicatorWidth;
  indicatorHeight = currentIndicatorHeight;

  if (controller.direction == Axis.horizontal) {
    if (info.progress <= 0.5) {
      final ratio = info.progress;
      final total1 = currentWidth + nextWidth;
      final total2 = currentIndicatorWidth + nextIndicatorWidth;

      indicatorWidth = 2 * currentIndicatorWidth * (0.5 - ratio) +
          ratio * (total1 + total2);
    }

    if (info.progress > 0.5) {
      final ratio = info.progress;
      final total1 = currentWidth + nextWidth;
      final total2 = currentIndicatorWidth + nextIndicatorWidth;

      indicatorWidth = 2 * nextIndicatorWidth * (ratio - 0.5) +
          (1 - ratio) * (total1 + total2);
    }

    final hNextWidth = nextWidth * 0.5;
    final hCurrentWidth = currentWidth * 0.5;
    final hCurrentIndicatorWidth = currentIndicatorWidth * 0.5;
    final hNextIndicatorWidth = nextIndicatorWidth * 0.5;

    if (info.progress <= 0.5) {
      left = currentOffsetX - hCurrentWidth - hCurrentIndicatorWidth;
      right = totalTabbarWidth - left! - indicatorWidth;
    }

    if (info.progress > 0.5) {
      right = totalTabbarWidth -
          currentOffsetX -
          hNextWidth -
          hNextIndicatorWidth;
      left = totalTabbarWidth - right! - indicatorWidth;
    }
  }

  if (controller.direction == Axis.vertical) {
    if (info.progress <= 0.5) {
      final ratio = info.progress;
      final total1 = currentHeight + nextHeight;
      final total2 = currentIndicatorHeight + nextIndicatorHeight;

      indicatorHeight = 2 * currentIndicatorHeight * (0.5 - ratio) +
          ratio * (total1 + total2);
    }

    if (info.progress > 0.5) {
      final ratio = info.progress;
      final total1 = currentHeight + nextHeight;
      final total2 = currentIndicatorHeight + nextIndicatorHeight;

      indicatorHeight = 2 * nextIndicatorHeight * (ratio - 0.5) +
          (1 - ratio) * (total1 + total2);
    }

    final hNextHeight = nextHeight * 0.5;
    final hCurrentHeight = currentHeight * 0.5;
    final hCurrentIndicatorHeight = currentIndicatorHeight * 0.5;
    final hNextIndicatorHeight = nextIndicatorHeight * 0.5;

    if (info.progress <= 0.5) {
      top = currentOffsetY - hCurrentHeight - hCurrentIndicatorHeight;
      bottom = tabBarViewHeight - top! - indicatorHeight;
    }

    if (info.progress > 0.5) {
      bottom = tabBarViewHeight -
          currentOffsetY -
          hNextHeight -
          hNextIndicatorHeight;
      top = tabBarViewHeight - bottom! - indicatorHeight;
    }
  }

  notifier.value = IndicatorPosition(
    top,
    left,
    right,
    bottom,
    indicatorWidth,
    indicatorHeight,
  );

  controller.callProgressListener(
    ScrollProgress(
      currentIndex: scroller.value.currentIndex,
      targetIndex: scroller.value.targetIndex,
      progress: scroller.value.progress,
      dir: scroller.value.dir,
    ),
  );
}