Apply physics boundary to scrollbar dragging (#72741)
This commit is contained in:
parent
3335bcbe40
commit
d4da441e53
@ -20,6 +20,7 @@ import 'primary_scroll_controller.dart';
|
|||||||
import 'scroll_controller.dart';
|
import 'scroll_controller.dart';
|
||||||
import 'scroll_metrics.dart';
|
import 'scroll_metrics.dart';
|
||||||
import 'scroll_notification.dart';
|
import 'scroll_notification.dart';
|
||||||
|
import 'scroll_position.dart';
|
||||||
import 'scrollable.dart';
|
import 'scrollable.dart';
|
||||||
import 'ticker_provider.dart';
|
import 'ticker_provider.dart';
|
||||||
|
|
||||||
@ -879,13 +880,18 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
|
|||||||
|
|
||||||
void _updateScrollPosition(double primaryDelta) {
|
void _updateScrollPosition(double primaryDelta) {
|
||||||
assert(_currentController != null);
|
assert(_currentController != null);
|
||||||
|
final ScrollPosition position = _currentController!.position;
|
||||||
|
|
||||||
// Convert primaryDelta, the amount that the scrollbar moved since the last
|
// Convert primaryDelta, the amount that the scrollbar moved since the last
|
||||||
// time _dragScrollbar was called, into the coordinate space of the scroll
|
// time _updateScrollPosition was called, into the coordinate space of the scroll
|
||||||
// position, and jump to that position.
|
// position, and jump to that position.
|
||||||
final double scrollOffsetLocal = scrollbarPainter.getTrackToScroll(primaryDelta);
|
final double scrollOffsetLocal = scrollbarPainter.getTrackToScroll(primaryDelta);
|
||||||
final double scrollOffsetGlobal = scrollOffsetLocal + _currentController!.position.pixels;
|
final double scrollOffsetGlobal = scrollOffsetLocal + position.pixels;
|
||||||
_currentController!.position.jumpTo(scrollOffsetGlobal);
|
if (scrollOffsetGlobal != position.pixels) {
|
||||||
|
// Ensure we don't drag into overscroll if the physics do not allow it.
|
||||||
|
final double physicsAdjustment = position.physics.applyBoundaryConditions(position, scrollOffsetGlobal);
|
||||||
|
position.jumpTo(scrollOffsetGlobal - physicsAdjustment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _maybeStartFadeoutTimer() {
|
void _maybeStartFadeoutTimer() {
|
||||||
|
@ -752,4 +752,56 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Scrollbar thumb cannot be dragged into overscroll if the physics do not allow', (WidgetTester tester) async {
|
||||||
|
final ScrollController scrollController = ScrollController();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: MediaQuery(
|
||||||
|
data: const MediaQueryData(),
|
||||||
|
child: PrimaryScrollController(
|
||||||
|
controller: scrollController,
|
||||||
|
child: RawScrollbar(
|
||||||
|
isAlwaysShown: true,
|
||||||
|
controller: scrollController,
|
||||||
|
child: const SingleChildScrollView(
|
||||||
|
child: SizedBox(width: 4000.0, height: 4000.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, 0.0, 800.0, 90.0),
|
||||||
|
color: const Color(0x66BCBCBC),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Try to drag the thumb into overscroll.
|
||||||
|
const double scrollAmount = -10.0;
|
||||||
|
final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// The physics should not have allowed us to enter overscroll.
|
||||||
|
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, 0.0, 800.0, 90.0),
|
||||||
|
color: const Color(0x66BCBCBC),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user