diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart index 49d9dacf3e..1e42279d1e 100644 --- a/packages/flutter/lib/src/widgets/scrollable.dart +++ b/packages/flutter/lib/src/widgets/scrollable.dart @@ -264,6 +264,13 @@ class ScrollableState extends State { super.dispose(); } + @override + void dependenciesChanged() { + _scrollBehavior = createScrollBehavior(); + didUpdateScrollBehavior(scrollOffset); + super.dependenciesChanged(); + } + /// The current scroll offset. /// /// The scroll offset is applied to the child widget along the scroll @@ -351,8 +358,6 @@ class ScrollableState extends State { /// or its createScrollBehavior callback is null, then return a new instance /// of [OverscrollWhenScrollableBehavior]. ExtentScrollBehavior createScrollBehavior() { - // TODO(hansmuller): this will not be called when the ScrollConfiguration changes. - // An override of dependenciesChanged() is probably needed. return ScrollConfiguration.of(context)?.createScrollBehavior(); } diff --git a/packages/flutter/test/widget/scroll_behavior_test.dart b/packages/flutter/test/widget/scroll_behavior_test.dart index 79dd83b4c4..d011a0b07e 100644 --- a/packages/flutter/test/widget/scroll_behavior_test.dart +++ b/packages/flutter/test/widget/scroll_behavior_test.dart @@ -2,17 +2,37 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; + +class TestScrollConfigurationDelegate extends ScrollConfigurationDelegate { + TestScrollConfigurationDelegate(this.flag); + + final bool flag; + + @override + TargetPlatform get platform => defaultTargetPlatform; + + @override + ExtentScrollBehavior createScrollBehavior() { + return flag + ? new BoundedBehavior(platform: platform) + : new UnboundedBehavior(platform: platform); + } + + @override + bool updateShouldNotify(TestScrollConfigurationDelegate old) => flag != old.flag; +} void main() { test('BoundedBehavior min scroll offset', () { - BoundedBehavior behavior = new BoundedBehavior( - contentExtent: 150.0, - containerExtent: 75.0, - minScrollOffset: -100.0, - platform: TargetPlatform.iOS - ); + BoundedBehavior behavior = new BoundedBehavior( + contentExtent: 150.0, + containerExtent: 75.0, + minScrollOffset: -100.0, + platform: TargetPlatform.iOS + ); + expect(behavior.minScrollOffset, equals(-100.0)); expect(behavior.maxScrollOffset, equals(-25.0)); @@ -35,4 +55,51 @@ void main() { expect(behavior.maxScrollOffset, equals(125.0)); expect(scrollOffset, equals(50.0)); }); + + testWidgets('Inherited ScrollConfiguration changed', (WidgetTester tester) async { + final GlobalKey scrollableKey = new GlobalKey(debugLabel: 'scrollable'); + TestScrollConfigurationDelegate delegate; + ExtentScrollBehavior behavior; + + await tester.pumpWidget( + new ScrollConfiguration( + delegate: new TestScrollConfigurationDelegate(true), + child: new ScrollableViewport( + scrollableKey: scrollableKey, + child: new Builder( + builder: (BuildContext context) { + delegate = ScrollConfiguration.of(context); + behavior = Scrollable.of(context).scrollBehavior; + return new Container(height: 1000.0); + } + ) + ) + ) + ); + + expect(delegate, isNotNull); + expect(delegate.flag, isTrue); + expect(behavior, new isInstanceOf()); + + // Same Scrollable, different ScrollConfiguration + await tester.pumpWidget( + new ScrollConfiguration( + delegate: new TestScrollConfigurationDelegate(false), + child: new ScrollableViewport( + scrollableKey: scrollableKey, + child: new Builder( + builder: (BuildContext context) { + delegate = ScrollConfiguration.of(context); + behavior = Scrollable.of(context).scrollBehavior; + return new Container(height: 1000.0); + } + ) + ) + ) + ); + + expect(delegate, isNotNull); + expect(delegate.flag, isFalse); + expect(behavior, new isInstanceOf()); + }); }