From 806fb93c211d11365d80f3eb2c4cc34cb0834ab3 Mon Sep 17 00:00:00 2001 From: Kate Lovett Date: Mon, 24 Oct 2022 18:03:50 -0500 Subject: [PATCH] Fix ScrollPosition.isScrollingNotifier.value for pointer scrolling (#113972) --- .../lib/src/widgets/scroll_position.dart | 2 -- .../scroll_position_with_single_context.dart | 4 ++- .../test/widgets/scroll_controller_test.dart | 31 +++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/flutter/lib/src/widgets/scroll_position.dart b/packages/flutter/lib/src/widgets/scroll_position.dart index 412179b0da..34e12dff6f 100644 --- a/packages/flutter/lib/src/widgets/scroll_position.dart +++ b/packages/flutter/lib/src/widgets/scroll_position.dart @@ -810,8 +810,6 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { /// /// This method is very similar to [jumpTo], but [pointerScroll] will /// update the [ScrollDirection]. - /// - // TODO(YeungKC): Support trackpad scroll, https://github.com/flutter/flutter/issues/23604. void pointerScroll(double delta); /// Calls [jumpTo] if duration is null or [Duration.zero], otherwise diff --git a/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart b/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart index c1a1666ec6..417a79b4a1 100644 --- a/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart +++ b/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart @@ -222,8 +222,10 @@ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc -delta > 0.0 ? ScrollDirection.forward : ScrollDirection.reverse, ); final double oldPixels = pixels; - forcePixels(targetPixels); + // Set the notifier before calling force pixels. + // This is set to false again after going ballistic below. isScrollingNotifier.value = true; + forcePixels(targetPixels); didStartScroll(); didUpdateScrollPositionBy(pixels - oldPixels); didEndScroll(); diff --git a/packages/flutter/test/widgets/scroll_controller_test.dart b/packages/flutter/test/widgets/scroll_controller_test.dart index be7935251c..96eeea898e 100644 --- a/packages/flutter/test/widgets/scroll_controller_test.dart +++ b/packages/flutter/test/widgets/scroll_controller_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:ui' as ui; + import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -362,4 +364,33 @@ void main() { expect(tester.getTopLeft(find.widgetWithText(SizedBox, 'Item 1')), Offset.zero); }); + + testWidgets('isScrollingNotifier works with pointer scroll', (WidgetTester tester) async { + Widget buildFrame(ScrollController controller) { + return Directionality( + textDirection: TextDirection.ltr, + child: ListView( + controller: controller, + children: List.generate(50, (int index) { + return SizedBox(height: 100.0, child: Text('Item $index')); + }).toList(), + ), + ); + } + + bool isScrolling = false; + final ScrollController controller = ScrollController(); + controller.addListener((){ + isScrolling = controller.position.isScrollingNotifier.value; + }); + await tester.pumpWidget(buildFrame(controller)); + final Offset scrollEventLocation = tester.getCenter(find.byType(ListView)); + final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse); + // Create a hover event so that |testPointer| has a location when generating the scroll. + testPointer.hover(scrollEventLocation); + await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 300.0))); + // When the listener was notified, the value of the isScrollingNotifier + // should have been true + expect(isScrolling, isTrue); + }); }