getOffsetToRevealExt method

RevealedOffset getOffsetToRevealExt(
  1. RenderObject target,
  2. double alignment, {
  3. bool esimationOnly = false,
  4. Rect? rect,
  5. Axis? axis,
})

Extended version of RenderAbstractViewport.getOffsetToReveal that takes child scroll obstruction into account and thus works properly with sliver that have childObstructionExtent set.

In addition this method allows the underlying sliver that is being queried for child scroll offset to access OffsetToRevealContext that contains information about the current query.

Implementation

RevealedOffset getOffsetToRevealExt(
  RenderObject target,
  double alignment, {
  bool esimationOnly = false,
  Rect? rect,
  Axis? axis,
}) {
  final context = OffsetToRevealContext(
    viewport: this,
    target: target,
    alignment: alignment,
    estimationOnly: esimationOnly,
    rect: rect,
    axis: axis,
  );
  OffsetToRevealContext._contexts.add(context);
  var result = getOffsetToReveal(target, alignment, rect: rect);
  OffsetToRevealContext._contexts.removeLast();
  final obstruction = target.getParentChildObstructionExtent();

  final resolvedAxis =
      (this is RenderViewportBase ? (this as RenderViewportBase).axis : axis);

  Rect shiftRect(Rect rect, double offset) {
    if (resolvedAxis == Axis.vertical) {
      return rect.shift(Offset(0, offset));
    } else {
      return rect.shift(Offset(offset, 0));
    }
  }

  if (obstruction.leading > 0) {
    final offset = obstruction.leading * (1.0 - alignment);
    result = RevealedOffset(
      offset: result.offset - offset,
      rect: shiftRect(result.rect, offset),
    );
  }
  if (obstruction.trailing > 0) {
    final offset = obstruction.trailing * alignment;
    result = RevealedOffset(
      offset: result.offset + offset,
      rect: shiftRect(result.rect, -offset),
    );
  }
  for (final callback in context._offsetResolvedCallbacks) {
    callback(result);
  }
  return result;
}