From 02bf594f36947608be2966812bbf70ff473edd9d Mon Sep 17 00:00:00 2001 From: xubaolin Date: Sat, 8 Jan 2022 08:20:17 +0800 Subject: [PATCH] fix a scrollbar bug (#95894) --- .../flutter/lib/src/widgets/scrollbar.dart | 2 +- .../flutter/test/widgets/scrollbar_test.dart | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/widgets/scrollbar.dart b/packages/flutter/lib/src/widgets/scrollbar.dart index 82e36eaed65..48568c6624c 100644 --- a/packages/flutter/lib/src/widgets/scrollbar.dart +++ b/packages/flutter/lib/src/widgets/scrollbar.dart @@ -1432,7 +1432,7 @@ class RawScrollbarState extends State with TickerProv case TargetPlatform.linux: case TargetPlatform.macOS: case TargetPlatform.windows: - newPosition = newPosition.clamp(0.0, position.maxScrollExtent); + newPosition = newPosition.clamp(position.minScrollExtent, position.maxScrollExtent); break; case TargetPlatform.iOS: case TargetPlatform.android: diff --git a/packages/flutter/test/widgets/scrollbar_test.dart b/packages/flutter/test/widgets/scrollbar_test.dart index c890049930a..ed724df040f 100644 --- a/packages/flutter/test/widgets/scrollbar_test.dart +++ b/packages/flutter/test/widgets/scrollbar_test.dart @@ -2075,6 +2075,87 @@ void main() { await tester.pumpAndSettle(); }); + testWidgets('Scrollbar thumb can be dragged when the scrollable widget has a negative minScrollExtent', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/95840 + + final ScrollController scrollController = ScrollController(); + final UniqueKey uniqueKey = UniqueKey(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: MediaQuery( + data: const MediaQueryData(), + child: ScrollConfiguration( + behavior: const ScrollBehavior().copyWith( + scrollbars: false, + ), + child: PrimaryScrollController( + controller: scrollController, + child: RawScrollbar( + isAlwaysShown: true, + controller: scrollController, + child: CustomScrollView( + center: uniqueKey, + slivers: [ + SliverToBoxAdapter( + child: Container( + height: 600.0, + ), + ), + SliverToBoxAdapter( + key: uniqueKey, + child: Container( + height: 600.0, + ), + ), + SliverToBoxAdapter( + child: Container( + height: 600.0, + ), + ), + ], + ), + ), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + expect(scrollController.offset, 0.0); + expect( + find.byType(RawScrollbar), + paints + ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0)) + ..rect( + rect: const Rect.fromLTRB(794.0, 200.0, 800.0, 400.0), + color: const Color(0x66BCBCBC), + ), + ); + + // Drag the thumb up to scroll up. + const double scrollAmount = -10.0; + final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 300.0)); + await tester.pumpAndSettle(); + await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount)); + await tester.pumpAndSettle(); + await dragScrollbarGesture.up(); + await tester.pumpAndSettle(); + + // The view has scrolled more than it would have by a swipe gesture of the + // same distance. + expect(scrollController.offset, lessThan(scrollAmount * 2)); + expect( + find.byType(RawScrollbar), + paints + ..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 600.0)) + ..rect( + rect: const Rect.fromLTRB(794.0, 190.0, 800.0, 390.0), + color: const Color(0x66BCBCBC), + ), + ); + }, variant: TargetPlatformVariant.all()); + test('ScrollbarPainter.shouldRepaint returns true when any of the properties changes', () { ScrollbarPainter createPainter({ Color color = const Color(0xFF000000),