在列表视图中滚动地图时如何避免滚动列表视图

时间:2019-05-18 08:31:07

标签: flutter flutter-layout

我有一个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"),);
    }
  )
),

我曾希望地图能够捕获手势,但它不会捕获手势,包含它的列表视图能够捕获所有手势。谁能建议我如何强制将列表中此项目的所有手势直接传递到地图,并在滚动列表中的其他项目时仍然使列表滚动?

2 个答案:

答案 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"),
              );
            },
          )
        ],
      ),
    );
  }