I'm in a bit of a pickle. I'm developing a Flutter app (currently using release 0.8.2 on Windows in Android Studio) and I can't seem to work out this one implementation detail. It's quite possible that it's just so simple I've missed it but I would appreciate it if someone could point me in the right direction!
My problem is: I have a custom color picker widget that I've created that is within a scrolling ListView. In order for the user to interact with the color picker widget properly, I need to stop the ListView from scrolling whenever the user is dragging the color pointer around within the picker but I need to then allow the ListView to be scrolled once the interaction is finished (so I can't just set the physics to a NeverScrollableScrollPhysics).
Here is a link to a screencap of the Interface
I'm currently using a Listener to handle interaction within the color picker and whenever the user drags the pointer around, the ListView scrolls as well. I have tried using a GestureDetector but the pan DestureDetector does not prevent the ListView from scrolling. I tried adding a vertical drag handler to the GestureDetector as well which did prevent the ListView from scrolling but doing this adds a minimum drag distance before the pointer moves since the GestureDetector tries to differentiate between a pan and a vertical drag.
I would love any suggestions or a pointer in the right direction. Thanks!
How do I stop list view scrolling in flutter? Flutter ListView – Never Scrollable You can make the ListView widget never scrollable by setting physics property to NeverScrollableScrollPhysics().
Use physics: const NeverScrollableScrollPhysics() in Listview Then you can prevent your widget from beeing scrolled.
By using ListView, only the items that are visible are mounted and painted. On the other hand, by using SingleChildScrollView+Column, the entire item list is mounted+painted, even if only a few items are visible. The tradeoff is that ListView is less flexible.
ClampingScrollPhysics class Null safety. Scroll physics for environments that prevent the scroll offset from reaching beyond the bounds of the content. This is the behavior typically seen on Android. See also: ScrollConfiguration, which uses this to provide the default scroll behavior on Android.
It's an old question, but as I struggled with the same issue myself, here is a hack:
bool _dragOverMap = false;
GlobalKey _pointerKey = new GlobalKey();
_checkDrag(Offset position, bool up) {
if (!up) {
// find your widget
RenderBox box = _pointerKey.currentContext.findRenderObject();
//get offset
Offset boxOffset = box.localToGlobal(Offset.zero);
// check if your pointerdown event is inside the widget (you could do the same for the width, in this case I just used the height)
if (position.dy > boxOffset.dy &&
position.dy < boxOffset.dy + box.size.height) {
setState(() {
_dragOverMap = true;
});
}
} else {
setState(() {
_dragOverMap = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Scroll Test"),
),
body: new Listener(
onPointerUp: (ev) {
_checkDrag(ev.position, true);
},
onPointerDown: (ev) {
_checkDrag(ev.position, false);
},
child: ListView(
// if dragging over your widget, disable scroll, otherwise allow scrolling
physics:
_dragOverMap ? NeverScrollableScrollPhysics() : ScrollPhysics(),
children: [
ListTile(title: Text("Tile to scroll")),
Divider(),
ListTile(title: Text("Tile to scroll")),
Divider(),
ListTile(title: Text("Tile to scroll")),
Divider(),
// Your widget that you want to prevent to scroll the Listview
Container(
key: _pointerKey, // key for finding the widget
height: 300,
width: double.infinity,
child: FlutterMap(
// ... just as example, could be anything, in your case use the color picker widget
),
),
],
),
),
);
}
}
Works fine for me, maybe one could simplify a few things, but you get the point.
It may help you.
bool _scroll = false;
_toggleScroll() {
_scroll = !_scroll;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
// switch scrolling
physics: _scroll ? NeverScrollableScrollPhysics() : ScrollPhysics(),
children: [],
),
);
}
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