How can I customize the physics
property of PageView to have for example a ClampingScrollPhysics for the first page (edge overflow) and a BouncingScrollPhysics for the last page?
(My use case is to load pages on demand when scrolling the last page.)
I tested this very little, so make sure you test it properly.
Code (see comments):
class MyScrollPhysics extends ScrollPhysics {
const MyScrollPhysics({super.parent});
@override
MyScrollPhysics applyTo(ScrollPhysics? ancestor) {
return MyScrollPhysics(parent: buildParent(ancestor));
}
@override
double applyBoundaryConditions(ScrollMetrics position, double value) {
/// This is the important part, where we can allow overscrolling of the
/// list, but not underscrolling.
if (value < position.pixels &&
position.pixels <= position.minScrollExtent) {
// Underscroll.
return value - position.pixels;
}
if (value < position.minScrollExtent &&
position.minScrollExtent < position.pixels) {
// Hit top edge.
return value - position.minScrollExtent;
}
/// If it's not a left or top boundary, then we allow overscrolling.
return .0;
}
@override
Simulation? createBallisticSimulation(
ScrollMetrics position,
double velocity,
) {
final tolerance = toleranceFor(position);
/// The simulation will be the typical bouncing scroll simulation.
if (velocity.abs() >= tolerance.velocity || position.outOfRange) {
return BouncingScrollSimulation(
spring: spring,
position: position.pixels,
velocity: velocity,
leadingExtent: position.minScrollExtent,
trailingExtent: position.maxScrollExtent,
tolerance: tolerance,
constantDeceleration: .0,
);
}
return null;
}
}
Usage:
PageView(
physics: const MyScrollPhysics(),
children: [
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.blue),
],
);