Skip to main content

Module physics

Module physics 

Source
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, the Simulation trait, the fling velocity constants, and the ScrollPhysics trait 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 — concrete Simulation implementations (the ballistic decay/spring curves a physics hands back from ScrollPhysics::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 a ScrollView/ ListView installs 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 ScrollPhysics that computes it — a clamping physics rejecting 100% of a boundary proposal still has an edge_pull to 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), AlwaysScrollableScrollPhysics and NeverScrollableScrollPhysics from widgets/scroll_physics.dart, driving the simulations in super::simulation.
rubber_band
RubberBand — the iOS-style rubber-band feel ScrollView/ListView used to have wired in, lifted out of those two widgets and behind the ScrollPhysics seam unchanged. It is no longer any platform’s default: both surfaces now install crate::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 Simulation curves — the ballistic motion a ScrollPhysics hands back once a gesture releases.

Structs§

ScrollMetrics
A read-only snapshot of a scroll surface’s extent/position, the argument every ScrollPhysics method reasons over (Flutter’s ScrollMetrics).
SpringDescription
A critically-damped-family spring’s physical parameters, feeding a Simulation built from ScrollPhysics::spring (Flutter’s SpringDescription).
Tolerance
The velocity/distance thresholds below which a ballistic simulation is considered settled — Flutter’s Tolerance, produced by toleranceFor.

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§

ScrollPhysics
A pluggable scroll-motion strategy — Flutter’s ScrollPhysics contract.
Simulation
A ballistic motion curve over time, produced by ScrollPhysics::create_ballistic_simulation and 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 as effect::OverscrollEffect::Stretch; a bouncing surface moves with the pull instead, so it shows as effect::OverscrollEffect::Translate.
default_physics
The physics a scroll surface installs when the app names none: Android → parity::Clamping (paired with effect::OverscrollEffect::Stretch, the Material-3-Expressive edge stretch), everywhere else → parity::Bouncing at parity::DecelerationRate::Normal (paired with effect::OverscrollEffect::Translate).