[英]Flutter - stop ListView scrolling when interacting with child widget
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.我正在开发一个 Flutter 应用程序(目前在 Android Studio 的 Windows 上使用 0.8.2 版),我似乎无法解决这个实现细节。 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.我的问题是:我在滚动 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).为了让用户与颜色选择器小部件正确交互,每当用户在选择器内拖动颜色指针时,我都需要停止滚动 ListView,但我需要在交互完成后允许滚动 ListView (所以我不能只是将物理设置为 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.我目前正在使用侦听器来处理颜色选择器中的交互,每当用户拖动指针时,ListView 也会滚动。 I have tried using a GestureDetector but the pan DestureDetector does not prevent the ListView from scrolling.我曾尝试使用 GestureDetector,但 Pan DestureDetector 不会阻止 ListView 滚动。 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.我也尝试向 GestureDetector 添加一个垂直拖动处理程序,这确实阻止了 ListView 滚动,但这样做会在指针移动之前增加最小拖动距离,因为 GestureDetector 试图区分平移和垂直拖动。
I would love any suggestions or a pointer in the right direction.我会喜欢任何建议或正确方向的指针。 Thanks!谢谢!
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: [], ), ); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.