Skip to content

Commit 421415b

Browse files
committed
sticky_header [nfc]: Fix childMainAxisPosition to handle paintOrigin nonzero
This fixes a latent bug: this method would give wrong answers if the sliver's paintOrigin were nonzero. See the new comments. The bug is latent because performLayout currently always produces a zero paintOrigin. But we'll start using paintOrigin soon, as part of making hit-testing work correctly when a sticky header is painted by one sliver but needs to encroach on the layout area of another sliver. The framework calls this method as part of hit-testing, so that requires fixing this bug too.
1 parent 0bbb43e commit 421415b

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

lib/widgets/sticky_header.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,17 +691,28 @@ class _RenderSliverStickyHeaderList extends RenderSliver with RenderSliverHelper
691691
double childMainAxisPosition(RenderObject child) {
692692
if (child == this.child) return 0.0;
693693
assert(child == header);
694+
694695
// We use Sliver*Physical*ParentData, so the header's position is stored in
695696
// physical coordinates. To meet the spec of `childMainAxisPosition`, we
696697
// need to convert to the sliver's coordinate system.
698+
699+
// First, use the sliver's layout coordinates (where the origin is the
700+
// point where the sliver's layout began, corresponding to
701+
// `constraints.scrollOffset`):
697702
final headerParentData = (header!.parentData as SliverPhysicalParentData);
698703
final paintOffset = headerParentData.paintOffset;
699-
return switch (constraints.growthAxisDirection) {
704+
final fromScrollOffset = switch (constraints.growthAxisDirection) {
700705
AxisDirection.right => paintOffset.dx,
701706
AxisDirection.left => geometry!.layoutExtent - header!.size.width - paintOffset.dx,
702707
AxisDirection.down => paintOffset.dy,
703708
AxisDirection.up => geometry!.layoutExtent - header!.size.height - paintOffset.dy,
704709
};
710+
711+
// Then the [childMainAxisPosition] spec wants a location relative to the
712+
// "leading _visible_ edge" of this sliver; and "visible" means paint,
713+
// not layout. The leading visible edge, expressed again in the sliver's
714+
// layout coordinates, is at `paintOrigin`.
715+
return fromScrollOffset - geometry!.paintOrigin;
705716
}
706717

707718
@override

0 commit comments

Comments
 (0)