diff --git a/packages/flutter/lib/src/rendering/sliver_persistent_header.dart b/packages/flutter/lib/src/rendering/sliver_persistent_header.dart index d2cca5ffcb..dbffe0f25c 100644 --- a/packages/flutter/lib/src/rendering/sliver_persistent_header.dart +++ b/packages/flutter/lib/src/rendering/sliver_persistent_header.dart @@ -393,6 +393,7 @@ abstract class RenderSliverFloatingPersistentHeader extends RenderSliverPersiste return; if (value == null) { _controller?.dispose(); + _controller = null; } else { if (_snapConfiguration != null && value.vsync != _snapConfiguration.vsync) _controller?.resync(value.vsync); diff --git a/packages/flutter/test/material/app_bar_test.dart b/packages/flutter/test/material/app_bar_test.dart index 39687a719a..4f712fd3a2 100644 --- a/packages/flutter/test/material/app_bar_test.dart +++ b/packages/flutter/test/material/app_bar_test.dart @@ -1422,4 +1422,67 @@ void main() { statusBarIconBrightness: Brightness.dark, )); }); + + testWidgets('Changing SliverAppBar snap from true to false', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/17598 + + const double appBarHeight = 256.0; + bool snap = true; + + await tester.pumpWidget( + MaterialApp( + home: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return Scaffold( + body: CustomScrollView( + slivers: [ + SliverAppBar( + expandedHeight: appBarHeight, + pinned: false, + floating: true, + snap: snap, + actions: [ + FlatButton( + child: const Text('snap=false'), + onPressed: () { + setState(() { + snap = false; + }); + }, + ), + ], + flexibleSpace: FlexibleSpaceBar( + background: Container( + height: appBarHeight, + color: Colors.orange, + ), + ), + ), + SliverList( + delegate: SliverChildListDelegate( + [ + Container(height: 1200.0, color: Colors.teal), + ], + ), + ), + ], + ), + ); + }, + ), + ), + ); + + TestGesture gesture = await tester.startGesture(const Offset(50.0, 400.0)); + await gesture.moveBy(const Offset(0.0, -100.0)); + await gesture.up(); + + await tester.tap(find.text('snap=false')); + await tester.pumpAndSettle(); + + gesture = await tester.startGesture(const Offset(50.0, 400.0)); + await gesture.moveBy(const Offset(0.0, -100.0)); + await gesture.up(); + await tester.pump(); + }); }