Fix issue where SliverPersistentHeader that is both floating and pinned would scroll down when scrolling past the beginning of the ScrollView (#27433)

This commit is contained in:
Sander Kersten 2019-02-21 00:42:15 +01:00 committed by Michael Goderbauer
parent f603642471
commit d1136e3109
2 changed files with 103 additions and 0 deletions

View File

@ -524,6 +524,7 @@ abstract class RenderSliverFloatingPinnedPersistentHeader extends RenderSliverFl
final double layoutExtent = maxExtent - constraints.scrollOffset; final double layoutExtent = maxExtent - constraints.scrollOffset;
geometry = SliverGeometry( geometry = SliverGeometry(
scrollExtent: maxExtent, scrollExtent: maxExtent,
paintOrigin: math.min(constraints.overlap, 0.0),
paintExtent: clampedPaintExtent, paintExtent: clampedPaintExtent,
layoutExtent: layoutExtent.clamp(0.0, clampedPaintExtent), layoutExtent: layoutExtent.clamp(0.0, clampedPaintExtent),
maxPaintExtent: maxExtent, maxPaintExtent: maxExtent,

View File

@ -112,4 +112,106 @@ void main() {
expect(render.geometry.paintExtent, availableHeight); expect(render.geometry.paintExtent, availableHeight);
expect(render.geometry.layoutExtent, 0.0); expect(render.geometry.layoutExtent, 0.0);
}); });
testWidgets('Pinned and floating SliverAppBar sticks to top the content is scroll down', (WidgetTester tester) async {
const Key anchor = Key('drag');
await tester.pumpWidget(
MaterialApp(
home: Center(
child: Container(
height: 300,
color: Colors.green,
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: <Widget>[
const SliverAppBar(
pinned: true,
floating: true,
expandedHeight: 100.0,
),
SliverToBoxAdapter(child: Container(key: anchor, color: Colors.red, height: 100)),
SliverToBoxAdapter(child: Container(height: 600, color: Colors.green)),
],
),
),
),
),
);
final RenderSliverFloatingPinnedPersistentHeader render = tester.renderObject(find.byType(SliverAppBar));
const double scrollDistance = 40;
final TestGesture gesture = await tester.press(find.byKey(anchor));
await gesture.moveBy(const Offset(0, scrollDistance));
await tester.pump();
expect(render.geometry.paintOrigin, -scrollDistance);
});
testWidgets('Floating SliverAppBar sticks to top the content is scroll down', (WidgetTester tester) async {
const Key anchor = Key('drag');
await tester.pumpWidget(
MaterialApp(
home: Center(
child: Container(
height: 300,
color: Colors.green,
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: <Widget>[
const SliverAppBar(
pinned: false,
floating: true,
expandedHeight: 100.0,
),
SliverToBoxAdapter(child: Container(key: anchor, color: Colors.red, height: 100)),
SliverToBoxAdapter(child: Container(height: 600, color: Colors.green)),
],
),
),
),
),
);
final RenderSliverFloatingPersistentHeader render = tester.renderObject(find.byType(SliverAppBar));
const double scrollDistance = 40;
final TestGesture gesture = await tester.press(find.byKey(anchor));
await gesture.moveBy(const Offset(0, scrollDistance));
await tester.pump();
expect(render.geometry.paintOrigin, -scrollDistance);
});
testWidgets('Pinned SliverAppBar sticks to top the content is scroll down', (WidgetTester tester) async {
const Key anchor = Key('drag');
await tester.pumpWidget(
MaterialApp(
home: Center(
child: Container(
height: 300,
color: Colors.green,
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: <Widget>[
const SliverAppBar(
pinned: true,
floating: false,
expandedHeight: 100.0,
),
SliverToBoxAdapter(child: Container(key: anchor, color: Colors.red, height: 100)),
SliverToBoxAdapter(child: Container(height: 600, color: Colors.green)),
],
),
),
),
),
);
final RenderSliverPinnedPersistentHeader render = tester.renderObject(find.byType(SliverAppBar));
const double scrollDistance = 40;
final TestGesture gesture = await tester.press(find.byKey(anchor));
await gesture.moveBy(const Offset(0, scrollDistance));
await tester.pump();
expect(render.geometry.paintOrigin, -scrollDistance);
});
} }