I'd like to create a grid list view in Flutter with an effect similar to the presented below on the right. Tiles' movement is delayed proportionally to the velocity. Similar effect can be seen here.
I tried to modify SliverGridDelegate
implementation to increase mainAxisStride
value depending on the scroll velocity.
In my CustomScrollView
I placed modified SliverGrid
(SliverAnimatedGrid
) with custom delegate that I called SliverGridDelegateWithFixedCrossAxisCountAndAnimation
which is based on SliverGridDelegateWithFixedCrossAxisCount
.
SliverGridDelegateWithFixedCrossAxisCountAndAnimation
accepts ScrollController
and uses its velocity in getLayout(SliverConstraints constraints)
function to increase mainAxisStride
of the grid.
Current implementation:
@override
SliverGridLayout getLayout(SliverConstraints constraints) {
assert(_debugAssertIsValid());
final double usableCrossAxisExtent =
constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1);
final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio;
// Here accessing scroll controller velocity
final velocity = (controller.position.activity.velocity / 100.0).clamp(0, 20);
return SliverGridRegularTileLayout(
crossAxisCount: crossAxisCount,
mainAxisStride: childMainAxisExtent + mainAxisSpacing + velocity,
crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
childMainAxisExtent: childMainAxisExtent,
childCrossAxisExtent: childCrossAxisExtent,
reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
);
}
This unfortunately is laggy and has some bugs because controller.position.activity
should not be accesses besides testing or in subclasses of scroll controller.
Full working example can be found here in this gist.
Do you have any ideas on how to efficiently implement this or similar effect?