applyPhysicsToUserOffset method
Used by DragScrollActivity and other user-driven activities to convert an offset in logical pixels as provided by the DragUpdateDetails into a delta to apply (subtract from the current position) using ScrollActivityDelegate.setPixels.
This is used by some ScrollPosition subclasses to apply friction during overscroll situations.
This method must not adjust parts of the offset that are entirely within
the bounds described by the given position
.
The given position
is only valid during this method call. Do not keep a
reference to it to use later, as the values may update, may not update, or
may update to reflect an entirely unrelated scrollable.
Implementation
@override
double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
// TODO: implement applyPhysicsToUserOffset
viewportRender ??=
findViewport(controller!.position?.context.storageContext);
if (controller!.headerMode!.value == RefreshStatus.twoLeveling) {
if (offset > 0.0) {
return parent!.applyPhysicsToUserOffset(position, offset);
}
} else {
if ((offset > 0.0 &&
viewportRender?.firstChild is! RenderSliverRefresh) ||
(offset < 0 && viewportRender?.lastChild is! RenderSliverLoading)) {
return parent!.applyPhysicsToUserOffset(position, offset);
}
}
if (position.outOfRange ||
controller!.headerMode!.value == RefreshStatus.twoLeveling) {
final double overscrollPastStart =
math.max(position.minScrollExtent - position.pixels, 0.0);
final double overscrollPastEnd = math.max(
position.pixels -
(controller!.headerMode!.value == RefreshStatus.twoLeveling
? 0.0
: position.maxScrollExtent),
0.0);
final double overscrollPast =
math.max(overscrollPastStart, overscrollPastEnd);
final bool easing = (overscrollPastStart > 0.0 && offset < 0.0) ||
(overscrollPastEnd > 0.0 && offset > 0.0);
final double friction = easing
// Apply less resistance when easing the overscroll vs tensioning.
? frictionFactor(
(overscrollPast - offset.abs()) / position.viewportDimension)
: frictionFactor(overscrollPast / position.viewportDimension);
final double direction = offset.sign;
return direction *
_applyFriction(overscrollPast, offset.abs(), friction) *
(dragSpeedRatio ?? 1.0);
}
return super.applyPhysicsToUserOffset(position, offset);
}