Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multidirectional scroll in flutter

I come from a web development background, and am used to being able to create an element that has both x and y overflow (allowing scrolling in any direction). I'm struggling to achieve the same functionality with Flutter.

Looking through the documentation, I've found SingleChildScrollView, but it only allows Axis.horizontal or Axis.vertical, not both.

So I have tried the following:

return SingleChildScrollView( // horizontal scroll widget
    scrollDirection: Axis.horizontal,
        child: SingleChildScrollView( // vertical scroll widget
            scrollDirection: Axis.vertical,
            child: ...content of the container etc...
        )
    );

This works for both x and y, but it doesn't allow for diagonal scrolling.

Is there a way to achieve diagonal scrolling, or is there a better material widget that I'm completely missing?

Thanks

like image 508
Matthew Evans Avatar asked Dec 18 '18 12:12

Matthew Evans


People also ask

How do you scroll horizontally Flutter?

To scroll a Flutter ListView widget horizontally, set scrollDirection property of the ListView widget to Axis. horizontal. This arranges the items side by side horzontally. Following is the basic syntax to arrange the items horizontally in a ListView and scroll them horizontally.

What is ScrollController in Flutter?

A scroll controller creates a ScrollPosition to manage the state specific to an individual Scrollable widget. To use a custom ScrollPosition, subclass ScrollController and override createScrollPosition. A ScrollController is a Listenable.


1 Answers

I've managed to find a solution, though it's not perfect:

I've created a StatefulWidget with an Offset _scrollOffset that uses a ClipRect with a child of type Transform. A transformation matrix (Matrix4.identity()..translate(_offset.dx, _offset.dy)) is applied to the transform.

A GestureDetector has an onPanUpdate callback assigned to update the scroll position. _scrollOffset += e.delta. This can be constrained to the boundaries of the widget by just setting the scroll position if it's too low or too high.

An Animation and AnimationController are used to set up fling velocity. onPanEnd provides the velocity of the last pan, so just performs a Tween with a fling based on that velocity.

The animation is stopped onTapDown so the user can stop the scroll velocity.

The main problem with this is it doesn't perfectly mimmick the Android or iOS scroll velocity, though I am working on trying to get it to work better using Flutter's provided ScrollSimulation classes.

like image 97
Matthew Evans Avatar answered Sep 20 '22 12:09

Matthew Evans