double applyBoundaryConditions(ScrollMetrics position, double value) {
参数 第一个参数就是滑动信息 第二个参数 就是新的即将设置的偏移量。 比如poistion.pixels = 100,用户向上滑动 10,那么value 就是 100.
applyBoundaryConditions 的使用逻辑理解
double setPixels(double newPixels) {
if (newPixels != pixels) {
final double overscroll = applyBoundaryConditions(newPixels);
final double oldPixels = pixels;
_pixels = newPixels - overscroll;
if (_pixels != oldPixels) {
notifyListeners();
didUpdateScrollPositionBy(pixels - oldPixels);
}
if (overscroll.abs() > precisionErrorTolerance) {
didOverscrollBy(overscroll);
return overscroll;
}
}
return 0.0;
}
newPixels 的值是当前处理完用户手指偏移量后的最终偏移量。
pixels - physics.applyPhysicsToUserOffset(this, delta)
overscroll 默认返回的是0.所以_pixels != oldPixels一般是成立的。就会调用 didUpdateScrollPositionBy来进行真正的滑动。overscroll.abs() > precisionErrorTolerance一般是不成立的。所以不会触发越界逻辑。
再以 ClampingScrollPhysics.applyPhysicsToUserOffset 实现为例
@override
double applyBoundaryConditions(ScrollMetrics position, double value) {
//1 下拉 并且越界
if (value < position.pixels && position.pixels <= position.minScrollExtent) {
// Underscroll.
return value - position.pixels;
}
//2 上拉 并且越界
if (position.maxScrollExtent <= position.pixels && position.pixels < value) {
// Overscroll.
return value - position.pixels;
}
//3 即将滑动小于最小值 但是 还没滑动小于最小值
if (value < position.minScrollExtent && position.minScrollExtent < position.pixels) {
// Hit top edge.
return value - position.minScrollExtent;
}
//4 还没滑动到最大值 并且即将超过最大值
if (position.pixels < position.maxScrollExtent && position.maxScrollExtent < value) {
// Hit bottom edge.
return value - position.maxScrollExtent;
}
return 0.0;
}
简单来说 ClampingScrollPhysics.applyPhysicsToUserOffset 返回的是超过边界的数值。 所以越界之后 overscroll不为0.
_pixels = newPixels - overscroll 计算的结果就是列表滑动到边界需要移动的距离。
第一种情况
_pixels = newPixels - (value - position.pixels)
value = newPixels
所以 _pixels = position.pixels
oldPixels = position.pixels
所以 _pixels != oldPixels 不成立。所以不会移动。
第二种情况
_pixels = newPixels - (value - position.pixels)
value = newPixels
所以 _pixels = position.pixels
oldPixels = position.pixels
所以 _pixels != oldPixels 不成立。所以不会移动。
第三种情况
_pixels = newPixels - (value - position.minScrollExtent)
value = newPixels
所以 _pixels = position.minScrollExtent
oldPixels = position.pixels
所以 _pixels != oldPixels 成立,移动距离为pixels - oldPixels = position.minScrollExtent - position.pixels
第四种情况
_pixels = newPixels - (value - position.maxScrollExtent)
value = newPixels
所以 _pixels = position.maxScrollExtent
oldPixels = position.pixels
所以 _pixels != oldPixels 成立,移动距离为pixels - oldPixels = position.maxScrollExtent - position.pixels