mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
fix an assertion causes by zero offset pointer scroll (#73016)
This commit is contained in:
parent
fc25d8b0cc
commit
217cd102bb
|
@ -629,8 +629,7 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
|
|||
|
||||
// Returns the offset that should result from applying [event] to the current
|
||||
// position, taking min/max scroll extent into account.
|
||||
double _targetScrollOffsetForPointerScroll(PointerScrollEvent event) {
|
||||
final double delta = _pointerSignalEventDelta(event);
|
||||
double _targetScrollOffsetForPointerScroll(double delta) {
|
||||
return math.min(math.max(position.pixels + delta, position.minScrollExtent),
|
||||
position.maxScrollExtent);
|
||||
}
|
||||
|
@ -653,9 +652,10 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
|
|||
if (_physics != null && !_physics!.shouldAcceptUserOffset(position)) {
|
||||
return;
|
||||
}
|
||||
final double targetScrollOffset = _targetScrollOffsetForPointerScroll(event);
|
||||
final double delta = _pointerSignalEventDelta(event);
|
||||
final double targetScrollOffset = _targetScrollOffsetForPointerScroll(delta);
|
||||
// Only express interest in the event if it would actually result in a scroll.
|
||||
if (targetScrollOffset != position.pixels) {
|
||||
if (delta != 0.0 && targetScrollOffset != position.pixels) {
|
||||
GestureBinding.instance!.pointerSignalResolver.register(event, _handlePointerScroll);
|
||||
}
|
||||
}
|
||||
|
@ -663,9 +663,10 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
|
|||
|
||||
void _handlePointerScroll(PointerEvent event) {
|
||||
assert(event is PointerScrollEvent);
|
||||
final double targetScrollOffset = _targetScrollOffsetForPointerScroll(event as PointerScrollEvent);
|
||||
if (targetScrollOffset != position.pixels) {
|
||||
position.pointerScroll(_pointerSignalEventDelta(event));
|
||||
final double delta = _pointerSignalEventDelta(event as PointerScrollEvent);
|
||||
final double targetScrollOffset = _targetScrollOffsetForPointerScroll(delta);
|
||||
if (delta != 0.0 && targetScrollOffset != position.pixels) {
|
||||
position.pointerScroll(delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1206,6 +1206,47 @@ void main() {
|
|||
expect(outerController.position.pixels, 0.0);
|
||||
expect(innerController.position.pixels, 0.0);
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/71949
|
||||
testWidgets('Zero offset pointer scroll should not trigger an assertion.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
Widget build(double height) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SizedBox(
|
||||
width: double.infinity,
|
||||
height: height,
|
||||
child: SingleChildScrollView(
|
||||
controller: controller,
|
||||
child: const SizedBox(
|
||||
width: double.infinity,
|
||||
height: 300.0,
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(build(200.0));
|
||||
expect(controller.position.pixels, 0.0);
|
||||
|
||||
controller.jumpTo(100.0);
|
||||
expect(controller.position.pixels, 100.0);
|
||||
|
||||
// Make the outer constraints larger that the scrollable widget is no longer able to scroll.
|
||||
await tester.pumpWidget(build(300.0));
|
||||
expect(controller.position.pixels, 100.0);
|
||||
expect(controller.position.maxScrollExtent, 0.0);
|
||||
|
||||
// Hover over the scroll view and create a zero offset pointer scroll.
|
||||
final Offset scrollable = tester.getCenter(find.byType(SingleChildScrollView));
|
||||
final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
|
||||
testPointer.hover(scrollable);
|
||||
await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 0.0)));
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
});
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
|
|
Loading…
Reference in a new issue