diff --git a/packages/flutter/lib/src/widgets/scroll_position.dart b/packages/flutter/lib/src/widgets/scroll_position.dart index d286918aa0..eb6ad4e151 100644 --- a/packages/flutter/lib/src/widgets/scroll_position.dart +++ b/packages/flutter/lib/src/widgets/scroll_position.dart @@ -506,6 +506,7 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { bool _pendingDimensions = false; ScrollMetrics? _lastMetrics; + Axis? _lastAxis; @override bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) { @@ -514,12 +515,14 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { assert(haveDimensions == (_lastMetrics != null)); if (!nearEqual(_minScrollExtent, minScrollExtent, Tolerance.defaultTolerance.distance) || !nearEqual(_maxScrollExtent, maxScrollExtent, Tolerance.defaultTolerance.distance) || - _didChangeViewportDimensionOrReceiveCorrection) { + _didChangeViewportDimensionOrReceiveCorrection || + _lastAxis != axis) { assert(minScrollExtent != null); assert(maxScrollExtent != null); assert(minScrollExtent <= maxScrollExtent); _minScrollExtent = minScrollExtent; _maxScrollExtent = maxScrollExtent; + _lastAxis = axis; final ScrollMetrics? currentMetrics = haveDimensions ? copyWith() : null; _didChangeViewportDimensionOrReceiveCorrection = false; _pendingDimensions = true; diff --git a/packages/flutter/test/rendering/viewport_test.dart b/packages/flutter/test/rendering/viewport_test.dart index 9d242b8409..14a1b2c5be 100644 --- a/packages/flutter/test/rendering/viewport_test.dart +++ b/packages/flutter/test/rendering/viewport_test.dart @@ -45,6 +45,50 @@ class _TestSliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate } void main() { + testWidgets('Scrollable widget scrollDirection update test', (WidgetTester tester) async { + final ScrollController controller = ScrollController(); + Widget buildFrame(Axis axis) { + return Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + height: 100.0, + width: 100.0, + child: SingleChildScrollView( + controller: controller, + scrollDirection: axis, + child: const SizedBox( + width: 200, + height: 200, + child: SizedBox.shrink(), + ), + ), + ), + ), + ); + } + + await tester.pumpWidget(buildFrame(Axis.vertical)); + expect(controller.position.pixels, 0.0); + + // Change the SingleChildScrollView.scrollDirection to horizontal. + await tester.pumpWidget(buildFrame(Axis.horizontal)); + expect(controller.position.pixels, 0.0); + + final TestGesture gesture = await tester.startGesture(const Offset(400.0, 300.0)); + // Drag in the vertical direction should not cause scrolling. + await gesture.moveBy(const Offset(0.0, 10.0)); + expect(controller.position.pixels, 0.0); + await gesture.moveBy(const Offset(0.0, -10.0)); + expect(controller.position.pixels, 0.0); + + // Drag in the horizontal direction should cause scrolling. + await gesture.moveBy(const Offset(-10.0, 0.0)); + expect(controller.position.pixels, 10.0); + await gesture.moveBy(const Offset(10.0, 0.0)); + expect(controller.position.pixels, 0.0); + }); + testWidgets('Viewport getOffsetToReveal - down', (WidgetTester tester) async { List children; await tester.pumpWidget(