我有一个ListView,在它的顶部有一个地图,我希望在滚动ListView时地图从视图中滚动出来,但我也希望用户能够与地图进行交互。因此,仅当用户在其他ListView小部件上滚动时才应进行滚动,而不是在用户在地图上滚动时应进行滚动,那么我希望将手势直接应用于地图。 不过目前,当用户在地图上滚动时,它会滚动整个ListView。
我尝试了另一个我在这里遇到的建议
In Flutter, how can a child widget prevent the scrolling of its scrollable parent?
我在上面的示例中的答案中添加了GestureDetector
,并将其包装在下面的示例中,但是这只是在滚动地图时阻止了ListView和Map的滚动。视频链接https://imgur.com/SeCRzUC
这是我的build方法返回的小部件。该代码取决于google_maps_flutter
插件。
Container(
height: MediaQuery.of(context).size.height,
child:
ListView.builder(
itemCount: 12 + 1,
itemBuilder: (context, index) {
if (index == 0) return GestureDetector(
onVerticalDragUpdate: (_){},
child: Container(
height: MediaQuery.of(context).size.height / 2,
child: GoogleMap(initialCameraPosition: initalPosition),
),
);
else return ListTile(title: Text("$index"),);
}
)
),
我曾希望地图能够捕获手势,但它不会捕获手势,包含它的列表视图能够捕获所有手势。谁能建议我如何强制将列表中此项目的所有手势直接传递到地图,并在滚动列表中的其他项目时仍然使列表滚动?
答案 0 :(得分:14)
公认的答案是使方法复杂化的方法,在我看来,它甚至行不通!它提供了从左到右的滚动,平移和缩放,但是从上到下的滚动仍然滚动了ListView
。
真正的解决方案非常简单,因为默认情况下GoogleMap
具有这些手势检测器。您仅需指定手势检测必须由GoogleMap
而不是ListView
进行优先处理。例如,可以通过以下方式为GoogleMap
对象提供一个EagerGestureRecognizer
。
ListView(
children: <Widget>[
Text('a'),
Text('b'),
GoogleMap(
...,
gestureRecognizers: {
Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer(),
),
},
),
],
)
通过这种方式,GoogleMap
会优先处理GoogleMap
对象上或上方发生的所有手势,而不是其他任何小部件。
答案 1 :(得分:1)
如果要在滚动时从屏幕上移出GoogleMap小部件,请用ListView包裹所有内容。
使用GoogleMap手势识别器覆盖ListView滚动实体。
由于ListView物理之间的冲突,禁用ListView.builder滚动物理。
首先导入依赖项:
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
构建方法:
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height / 2,
child: GoogleMap(
initialCameraPosition:
CameraPosition(target: LatLng(41, 29), zoom: 10),
gestureRecognizers: Set()
..add(
Factory<PanGestureRecognizer>(() => PanGestureRecognizer()))
..add(
Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer()),
)
..add(
Factory<HorizontalDragGestureRecognizer>(
() => HorizontalDragGestureRecognizer()),
)
..add(
Factory<ScaleGestureRecognizer>(
() => ScaleGestureRecognizer()),
),
),
),
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: 12,
itemBuilder: (context, index) {
return ListTile(
title: Text("$index"),
);
},
)
],
),
);
}