Description
Issue Description:
While implementing a RefreshIndicator, I encountered an issue when trying to replicate the "cancel refresh" behavior shown in the Ice cream example (where the indicator smoothly retracts upward on user cancellation).
To achieve this, I modified the scroll physics to:AlwaysScrollableScrollPhysics(parent: ClampingWithOverscrollPhysics(state: controller)
The indicator animation now works as intended, but a new problem arises:
When scrolling to the bottom of the list (assuming a top-triggered indicator), attempting to drag downward (ScrollDirection.forward) causes the list to feel "stuck" – scrolling becomes unresponsive to finger movement. Multiple attempts are often needed to trigger the scroll.
Reproduction Steps:
Reproducible in the Custom Refresh Indicator Live Example - Custom Material Indicator by:
-
Scroll to the list bottom
-
Attempt downward drag (forward scroll direction)
Also occurs when modifying the physics in the Ice Cream Indicator example.
Request:
How can I resolve this scroll jank while maintaining the desired indicator cancellation behavior? Are there adjustments to the physics configuration or alternative approaches to ensure smooth scrolling at list boundaries?
When scroll jank occurs The scroll notification behavior is:
ScrollStartNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), DragStartDetails(Offset(391.3, 591.0)))
UserScrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), direction: ScrollDirection.forward)
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -0.7, velocity: 0.0, DragUpdateDetails(Offset(0.0, 0.7)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -1.3, velocity: 0.0, DragUpdateDetails(Offset(0.0, 1.3)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -0.7, velocity: 0.0, DragUpdateDetails(Offset(0.0, 0.7)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -1.3, velocity: 0.0, DragUpdateDetails(Offset(0.0, 1.3)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -0.7, velocity: 0.0, DragUpdateDetails(Offset(0.0, 0.7)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -1.3, velocity: 0.0, DragUpdateDetails(Offset(0.0, 1.3)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -0.7, velocity: 0.0, DragUpdateDetails(Offset(0.0, 0.7)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -1.3, velocity: 0.0, DragUpdateDetails(Offset(0.0, 1.3)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -0.7, velocity: 0.0, DragUpdateDetails(Offset(0.0, 0.7)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -1.3, velocity: 0.0, DragUpdateDetails(Offset(0.0, 1.3)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -0.7, velocity: 0.0, DragUpdateDetails(Offset(0.0, 0.7)))
OverscrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), overscroll: -1.3, velocity: 0.0, DragUpdateDetails(Offset(0.0, 1.3)))
ScrollEndNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), DragEndDetails(Velocity(0.0, 0.0)))
UserScrollNotification(depth: 0 (local), FixedScrollMetrics(908.7..[819.3]..0.0), direction: ScrollDirection.idle)
I'm new to Flutter, thank you so much for your help!