I have a PageView/ListView with a viewportFraction
of 0.8 to show a preview of the next slide. It looks something like this:
It seems like it is not possible to have the current slide aligned to the left, as shown below. Is that correct?
I found this solution. Using a horizontally scrolling ListView with PageScrollPhysics()
, at first looked promising however, this way the page snapping is based on the screen width (?) and not on the ListView children, so the snapping is off by quite a bit.
Is there a way to have the page snapping based on the size of the children?
My answer comes a bit late but it might help others looking for the same thing. the PageScrollPhysics uses the screen width. You need to create your own ScrollPhysics that uses your item width to paginate. here is an example:
ListView.builder(
physics: PagingScrollPhysics(itemDimension: YOUR_ITEM_WIDTH),
itemCount:items.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return YOUR_CHILD();
}
)
And the new ScrollPhysics:
import 'package:flutter/material.dart';
class PagingScrollPhysics extends ScrollPhysics {
final double itemDimension;
PagingScrollPhysics({required this.itemDimension, ScrollPhysics? parent}) : super(parent: parent);
@override
PagingScrollPhysics applyTo(ScrollPhysics? ancestor) {
return PagingScrollPhysics(itemDimension: itemDimension, parent: buildParent(ancestor));
}
double _getPage(ScrollMetrics position) {
return position.pixels / itemDimension;
}
double _getPixels(double page) {
return page * itemDimension;
}
double _getTargetPixels(ScrollMetrics position, Tolerance tolerance, double velocity) {
double page = _getPage(position);
if (velocity < -tolerance.velocity) {
page -= 0.5;
} else if (velocity > tolerance.velocity) {
page += 0.5;
}
return _getPixels(page.roundToDouble());
}
@override
Simulation? createBallisticSimulation(ScrollMetrics position, double velocity) {
if ((velocity <= 0.0 && position.pixels <= position.minScrollExtent) || (velocity >= 0.0 && position.pixels >= position.maxScrollExtent)) return super.createBallisticSimulation(position, velocity);
final Tolerance tolerance = this.tolerance;
final double target = _getTargetPixels(position, tolerance, velocity);
if (target != position.pixels) return ScrollSpringSimulation(spring, position.pixels, target, velocity, tolerance: tolerance);
return null;
}
@override
bool get allowImplicitScrolling => false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With