Как убрать инерцию при прокрутке ListView?
Для реализации докрутки списка ListView в нужный оффсет я использую метод контроллера animateTo.
При этом возникает эффект инерции, то есть при отработке анимации элемент списка "проскакивает" заданный оффсет и потом возвращается в нужную позицию (эффект обратной связи)
Мне необходимо убрать этот эффект инерции. Для этого я написал свой собственный CustomScrollPhysics класс:
class CustomScrollPhysics extends ScrollPhysics {
const CustomScrollPhysics({ScrollPhysics parent}) : super(parent: parent);
@override
double get minFlingVelocity => double.infinity;
@override
double get maxFlingVelocity => double.infinity;
@override
double get minFlingDistance => double.infinity;
@override
SpringDescription get spring => SpringDescription(damping: 0.1);
@override
CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
return CustomScrollPhysics(parent: buildParent(ancestor));
}
}
Однако эта реализация убирает физику инерции ТОЛЬКО при обратном движении (если листаем от большего индекса к меньшему), не пойму почему именно так... Как убрать эффект инерции в обе стороны? Вот ссылка на DartPad, где показан рабочий пример
Ответы (1 шт):
При вертикальной "докрутке" ошибка в вычислении добавки к смещению приводила к резкому сдвигу (fling) который и создавал эффект инерции.
var halfOfTheHeight = cardHeight / 2;
var offsetOfItem = metrics.extentBefore % cardHeight;
if (offsetOfItem < halfOfTheHeight) {
final offset = metrics.extentBefore - offsetOfItem;
Future.delayed(Duration(milliseconds: 50), () {
_verticalController.animateTo(offset,
duration: Duration(milliseconds: 1000),
curve: Curves.fastOutSlowIn);
});
} else if (offsetOfItem > halfOfTheHeight) {
// здесь была ошибка: metrics.extentBefore + offsetOfItem
final offset = metrics.extentBefore + cardHeight - offsetOfItem;
Future.delayed(Duration(milliseconds: 50), () {
_verticalController.animateTo(offset,
duration: Duration(milliseconds: 1000),
curve: Curves.fastOutSlowIn);
});
}