Commit 62cc326a authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Constrain app bar header paint origin on iOS overscroll (#8517)

Prevent the app bar header from being overscrolled on iOS by setting
paintOrigin to the overlap.
parent 1f7b8ae1
......@@ -209,6 +209,7 @@ abstract class RenderSliverScrollingPersistentHeader extends RenderSliverPersist
final double paintExtent = maxExtent - constraints.scrollOffset;
geometry = new SliverGeometry(
scrollExtent: maxExtent,
paintOrigin: math.min(constraints.overlap, 0.0),
paintExtent: paintExtent.clamp(0.0, constraints.remainingPaintExtent),
maxPaintExtent: maxExtent,
hasVisualOverflow: true, // Conservatively say we do have overflow to avoid complexity.
......@@ -271,6 +272,7 @@ abstract class RenderSliverFloatingPersistentHeader extends RenderSliverPersiste
final double layoutExtent = maxExtent - constraints.scrollOffset;
geometry = new SliverGeometry(
scrollExtent: maxExtent,
paintOrigin: math.min(constraints.overlap, 0.0),
paintExtent: paintExtent.clamp(0.0, constraints.remainingPaintExtent),
layoutExtent: layoutExtent.clamp(0.0, constraints.remainingPaintExtent),
maxPaintExtent: maxExtent,
......
......@@ -182,6 +182,35 @@ void main() {
verifyActualBoxPosition(tester, find.byType(Container), 0, new Rect.fromLTWH(0.0, -delegate.maxExtent * 0.4, 800.0, delegate.maxExtent * 0.5));
verifyPaintPosition(key3, const Offset(0.0, 0.0), true);
});
testWidgets('Sliver appbars - floating - overscroll gap is below header', (WidgetTester tester) async {
await tester.pumpWidget(
new CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: <Widget>[
new SliverPersistentHeader(delegate: new TestDelegate(), floating: true),
new SliverList(
delegate: new SliverChildListDelegate(<Widget>[
new SizedBox(
height: 300.0,
child: new Text('X'),
),
]),
),
],
),
);
expect(tester.getTopLeft(find.byType(Container)), Point.origin);
expect(tester.getTopLeft(find.text('X')), const Point(0.0, 200.0));
ScrollPosition position = tester.state<ScrollableState>(find.byType(Scrollable)).position;
position.jumpTo(-50.0);
await tester.pump();
expect(tester.getTopLeft(find.byType(Container)), Point.origin);
expect(tester.getTopLeft(find.text('X')), const Point(0.0, 250.0));
});
}
class TestDelegate extends SliverPersistentHeaderDelegate {
......
......@@ -67,6 +67,35 @@ void main() {
Rect rect = new Rect.fromPoints(box.localToGlobal(Point.origin), box.localToGlobal(box.size.bottomRight(Point.origin)));
expect(rect, equals(new Rect.fromLTWH(0.0, -195.0, 800.0, 200.0)));
});
testWidgets('Sliver appbars - scrolling - overscroll gap is below header', (WidgetTester tester) async {
await tester.pumpWidget(
new CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: <Widget>[
new SliverPersistentHeader(delegate: new TestDelegate()),
new SliverList(
delegate: new SliverChildListDelegate(<Widget>[
new SizedBox(
height: 300.0,
child: new Text('X'),
),
]),
),
],
),
);
expect(tester.getTopLeft(find.byType(Container)), Point.origin);
expect(tester.getTopLeft(find.text('X')), const Point(0.0, 200.0));
ScrollPosition position = tester.state<ScrollableState>(find.byType(Scrollable)).position;
position.jumpTo(-50.0);
await tester.pump();
expect(tester.getTopLeft(find.byType(Container)), Point.origin);
expect(tester.getTopLeft(find.text('X')), const Point(0.0, 250.0));
});
}
class TestDelegate extends SliverPersistentHeaderDelegate {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment