Issue
I have a relatively complex Listview setup, where one Listview acts as a scrolling parent of a horizontal Listview, which acts as a parent to a third vertical Listview.
Here is an image of the general idea of the layout: https://cdn.discordapp.com/attachments/752981111738466467/895739370227773480/IMG_20211007_142732.jpg.
I’m having trouble getting the middle Listview, the horizontal Listview (marked 2 in the image), to scroll.
ConstrainedBox(
constraints: BoxConstraints(...),
child: ListView.builder( // This is Listview 1
controller: ScrollController(),
itemCount: itemCount,
itemBuilder: (context, worldIndex) {
return ConstrainedBox(
constraints: BoxConstraints(...),
child: ListView.builder( // This is Listview 2
controller: ScrollController(),
itemCount: ...,
scrollDirection: Axis
.horizontal, // grows horizontally to show the hierarchy of one card (the card selected in the hierarchy above it, or for the first level, the world) to its children
itemBuilder: (context, index) {
...
return ConstrainedBox(
constraints: BoxConstraints(...),
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
decoration: ...,
),
child: ListView.builder( // This is Listview 3
controller: ScrollController(),
itemCount: getNumChildren(index),
itemBuilder: (context, index2) {
return ...;
}),
)));
}));
}));
For brevity, I have removed several parts of my code and replaced them with elipses. I don’t think it is likely that any of these areas could cause any issues with the Listview, but please let me know if they could.
Edit: The code I have already works properly, aside from the horizontal Listview not scrolling. My solution needs to have a dynamically expandable Listview at each level of the tree (1, 2, and 3, in the image, for example). The primary target platform for this is Windows.
I’m assuming the issue involves a problem with which Listview wins the GestureArena, but I am currently at a loss in how to work around that issue, providing a way to scroll all of available Listviews.
Thank you in advance, and I hope you have a great day!
Solution
The solution to this turned out to be that Flutter has intentionally turned off the ability to scroll horizontally using both scroll wheel and dragging for Windows (or at least, that’s what seems to be the case according to what I was able to find in this issue).
To solve that, they have made a migration guide here.
Following the guide, it is extremely simple to override the drag devices used in order to re-enable the intended drag scrolling. This still does not enable scrolling horizontally with a mouse wheel, but for my code that is not an issue.
class CustomScrollBehavior extends MaterialScrollBehavior { // A custom scroll behavior allows setting whichever input device types that we want, and in this case, we want mouse and touch support.
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
};
}
Then, in the actual Listview
‘s code, we set a ScrollConfiguration
with this new class as its behavior.
ScrollConfiguration(
behavior: CustomScrollBehavior(),
child: Listview.Builder(
controller: ScrollController(),
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
...
})
Answered By – Cody Moore
Answer Checked By – David Marino (FlutterFixes Volunteer)