Expand description
Pluggable scroll physics, mirroring Flutter’s ScrollPhysics contract: a
chainable strategy object a scroll surface (today crate::ScrollView/
crate::ListView, hard-coded to one behavior) consults for user-offset
mapping, boundary rejection, and post-release ballistic motion instead of
having that math wired in directly.
§Module map
Three seams, each its own file:
- This file — the shared vocabulary every physics implementation and
consumer builds against:
ScrollMetrics,Tolerance,SpringDescription, theSimulationtrait, the fling velocity constants, and theScrollPhysicstrait itself. effect— [OverscrollEffect], how boundary-rejected displacement is visualized (translate vs. paint-side stretch vs. none) — orthogonal to the physics that computes the displacement in the first place.simulation— concreteSimulationimplementations (the ballistic decay/spring curves a physics hands back fromScrollPhysics::create_ballistic_simulation).rubber_band— the pre-seam rubber-band feel, now an opt-in.parity— the platform-parity physics (Bouncing/Clamping/AlwaysScrollable/NeverScrollable) both scroll surfaces default to.- This file also carries the platform-adaptive default selection itself —
default_physics/default_overscroll_effect, what aScrollView/ListViewinstalls when the app names no physics of its own.
§Design ruling: rejected excess is reported, not absorbed
ScrollPhysics::apply_boundary_conditions returns the portion of a
proposed position a physics rejects — the part the scroll position must
not move to — separately from anything about how that rejection looks on
screen. A widget accumulates the rejected excess itself (as its own
edge_pull state, outside this module) rather than this trait owning any
visual displacement. This is deliberate: pull-to-refresh triggering and the
effect::OverscrollEffect::Stretch paint effect both need to read how far
past the edge a gesture is pulling even under a clamping physics
(apply_boundary_conditions rejecting 100% of the excess, i.e. the
position itself never leaves range) — so a clamping physics still supports
both features, it just never lets edge_pull show up as a position change.
Modules§
- effect
- How overscroll displacement/pull is visualized, independent of the
ScrollPhysicsthat computes it — a clamping physics rejecting 100% of a boundary proposal still has anedge_pullto paint an effect from (see the module docs’s design ruling), and a bouncing physics letting the position itself move past the edge can be paired with any of these the same way. - parity
- The platform-parity physics: ports of Flutter’s
BouncingScrollPhysics(iOS),ClampingScrollPhysics(Android),AlwaysScrollableScrollPhysicsandNeverScrollableScrollPhysicsfromwidgets/scroll_physics.dart, driving the simulations insuper::simulation. - rubber_
band RubberBand— the iOS-style rubber-band feelScrollView/ListViewused to have wired in, lifted out of those two widgets and behind theScrollPhysicsseam unchanged. It is no longer any platform’s default: both surfaces now installcrate::physics::default_physics’s platform-parity choice, and this is the opt-in an app names (.physics(RubberBand::new())) to keep the pre-seam feel — a flat resistance with the widgets’ own legacy fling/settle, rather than a depth-aware curve with a ballistic spring.- simulation
- Concrete
Simulationcurves — the ballistic motion aScrollPhysicshands back once a gesture releases.
Structs§
- Scroll
Metrics - A read-only snapshot of a scroll surface’s extent/position, the argument
every
ScrollPhysicsmethod reasons over (Flutter’sScrollMetrics). - Spring
Description - A critically-damped-family spring’s physical parameters, feeding a
Simulationbuilt fromScrollPhysics::spring(Flutter’sSpringDescription). - Tolerance
- The velocity/distance thresholds below which a ballistic simulation is
considered settled — Flutter’s
Tolerance, produced bytoleranceFor.
Constants§
- MAX_
FLING_ VELOCITY - The fastest fling speed (px/s) a physics honors — Flutter’s
kMaxFlingVelocity. A release faster than this clamps to it. - MIN_
FLING_ VELOCITY - The minimum release speed (px/s) that starts a fling — Flutter’s
kMinFlingVelocity. A release slower than this is treated as a plain drag-end, never a fling.
Traits§
- Scroll
Physics - A pluggable scroll-motion strategy — Flutter’s
ScrollPhysicscontract. - Simulation
- A ballistic motion curve over time, produced by
ScrollPhysics::create_ballistic_simulationand driven by the consuming widget after a gesture release (fling decay, a spring-back, or any other closed-form or iterative curve).
Functions§
- default_
overscroll_ effect - The overscroll visual paired with
default_physics: Android’s clamping position never leaves the range, so the pull shows aseffect::OverscrollEffect::Stretch; a bouncing surface moves with the pull instead, so it shows aseffect::OverscrollEffect::Translate. - default_
physics - The physics a scroll surface installs when the app names none: Android →
parity::Clamping(paired witheffect::OverscrollEffect::Stretch, the Material-3-Expressive edge stretch), everywhere else →parity::Bouncingatparity::DecelerationRate::Normal(paired witheffect::OverscrollEffect::Translate).