Stop CupertinoScrollbar's track from paging the scroll view on tap (#152197)

Fixes https://github.com/flutter/flutter/issues/120429
This commit is contained in:
Victor Sanni 2024-07-29 16:02:02 -07:00 committed by GitHub
parent b3bb00c4d9
commit e33eb5b46e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 4 deletions

View File

@ -211,6 +211,14 @@ class _CupertinoScrollbarState extends RawScrollbarState<CupertinoScrollbar> {
}
}
@override
void handleTrackTapDown(TapDownDetails details) {
// On iOS, tapping the track does not page towards the position of the tap.
if (ScrollConfiguration.of(context).getPlatform(context) != TargetPlatform.iOS) {
super.handleTrackTapDown(details);
}
}
@override
void dispose() {
_thicknessAnimationController.dispose();

View File

@ -1799,7 +1799,11 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
_cachedController = null;
}
void _handleTrackTapDown(TapDownDetails details) {
/// Handler called when the track is tapped in order to page in the tapped
/// direction.
@protected
@mustCallSuper
void handleTrackTapDown(TapDownDetails details) {
// The Scrollbar should page towards the position of the tap on the track.
assert(_debugCheckHasValidScrollPosition());
_cachedController = _effectiveScrollController;
@ -2018,7 +2022,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
customPaintKey: _scrollbarPainterKey,
),
(_TrackTapGestureRecognizer instance) {
instance.onTapDown = _handleTrackTapDown;
instance.onTapDown = handleTrackTapDown;
},
);

View File

@ -1017,7 +1017,7 @@ void main() {
await tester.pump(kScrollbarFadeDuration);
});
testWidgets('Tapping the track area pages the Scroll View', (WidgetTester tester) async {
testWidgets('Tapping the track area pages the Scroll View except on iOS', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
await tester.pumpWidget(
@ -1075,7 +1075,64 @@ void main() {
rrect: RRect.fromLTRBR(794.0, 3.0, 797.0, 359.4, const Radius.circular(1.5)),
),
);
});
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{TargetPlatform.iOS}));
testWidgets('Tapping the track area does not page the Scroll View on iOS', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: const MediaQueryData(),
child: CupertinoScrollbar(
thumbVisibility: true,
controller: scrollController,
child: SingleChildScrollView(
controller: scrollController,
child: const SizedBox(width: 1000.0, height: 1000.0),
),
),
),
),
);
await tester.pumpAndSettle();
expect(scrollController.offset, 0.0);
expect(
find.byType(CupertinoScrollbar),
paints..rrect(
color: _kScrollbarColor.color,
rrect: RRect.fromLTRBR(794.0, 3.0, 797.0, 359.4, const Radius.circular(1.5)),
),
);
// Tap on the track area below the thumb.
await tester.tapAt(const Offset(796.0, 550.0));
await tester.pumpAndSettle();
expect(scrollController.offset, 0.0);
expect(
find.byType(CupertinoScrollbar),
paints..rrect(
color: _kScrollbarColor.color,
rrect: RRect.fromLTRBR(794.0, 3.0, 797.0, 359.4, const Radius.circular(1.5)),
),
);
// Tap on the track area above the thumb.
await tester.tapAt(const Offset(796.0, 50.0));
await tester.pumpAndSettle();
expect(scrollController.offset, 0.0);
expect(
find.byType(CupertinoScrollbar),
paints..rrect(
color: _kScrollbarColor.color,
rrect: RRect.fromLTRBR(794.0, 3.0, 797.0, 359.4, const Radius.circular(1.5)),
),
);
}, variant: TargetPlatformVariant.only(TargetPlatform.iOS));
testWidgets('Throw if interactive with the bar when no position attached', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();