【问题标题】:How to avoid scrolling listview when scrolling in map within listview在列表视图中滚动地图时如何避免滚动列表视图
【发布时间】:2019-10-05 10:14:35
【问题描述】:

我有一个 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

这是我的构建方法返回的小部件。此代码依赖于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"),);
    }
  )
),

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

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    编辑:campovski 下面的答案是更新后的答案。

    Depreciated Answer:

    • 如果您想在滚动时从屏幕上移出 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"),
                  );
                },
              )
            ],
          ),
        );
      }
    

    【讨论】:

    • 感谢您的回答!我是否说 ListView 现在根本不会滚动?抱歉,在重读我最初的帖子时,我意识到我没有明确表示如果用户在列表的任何其他部分(地图除外)滚动,我仍然希望 ListView 滚动
    • @diarmuid 这正是你想要的,试试看 :)
    【解决方案2】:

    接受的答案(Eset Mehmet 的答案在撰写本文时被标记为例外)太复杂了,就我而言,它甚至不起作用!它提供从左到右的滚动、平移和缩放,但从上到下的滚动仍然滚动ListView

    真正的解决方案非常简单,因为GoogleMap 默认具有这些手势检测器。您只需指定手势检测必须由GoogleMap 而不是ListView 优先。这可以通过以下方式为GoogleMap 对象提供EagerGestureRecognizer 来实现。

    ListView(
      children: <Widget>[
        Text('a'),
        Text('b'),
        GoogleMap(
          ...,
          gestureRecognizers: {
            Factory<OneSequenceGestureRecognizer>(
              () => EagerGestureRecognizer(),
            ),
          },
        ),
      ],
    )
    

    这样,GoogleMap 对象上或上方发生的所有手势都将由GoogleMap 优先处理,而不是任何其他小部件。

    【讨论】:

    • 感谢@campovski,这个 5 行解决方案对我来说非常有用。我可以在 ListView 中滚动,然后当我触摸地图时我可以在地图内滚动。
    • @eluong 很高兴它有帮助,这对我来说是一场噩梦,所以我决定分享我的解决方案。
    • @campovski 谢谢!这就是我一直在寻找的
    • 不需要 EagerGestureRecognizer,试试这个解决方案 stackoverflow.com/questions/54280541/… 有了这个解决方案,您仍然可以使用 Pageview。急切的识别器将不允许页面浏览量滚动
    猜你喜欢
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多