You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web中DraggableScrollableSheet拖动时GoogleMap联动滚动问题

解决Web端拖动DraggableScrollableSheet时GoogleMap跟随滚动的问题

这个问题源于Web端触摸事件的冒泡特性——拖动Sheet的事件会传递到底层的GoogleMap,导致地图同步滚动。可以通过动态控制地图的触摸响应状态来解决,具体实现如下:

方案:结合NotificationListener与IgnorePointer拦截事件

  1. 在页面State中添加布尔变量,标记是否需要阻止地图响应触摸:
bool _shouldBlockMap = false;
  1. 用NotificationListener包裹DraggableScrollableSheet,监听Sheet的拖动状态:
    当Sheet处于拖动状态时(extentChanged为true),将_shouldBlockMap设为true;拖动结束后恢复为false。
  2. 用IgnorePointer包裹GoogleMap,根据_shouldBlockMap的值控制地图是否接收触摸事件。

修改后的完整代码:

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter/foundation.dart'; // 用于判断平台(可选)

class MapPage extends StatefulWidget {
  const MapPage({super.key});

  @override
  State<MapPage> createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> {
  static const CameraPosition _kGooglePlex = CameraPosition(
    target: LatLng(37.42796133580664, -122.085749655962),
    zoom: 14.4746,
  );
  bool _shouldBlockMap = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          IgnorePointer(
            // 可选:仅在Web端生效,不干扰Android端原有逻辑
            ignoring: kIsWeb && _shouldBlockMap,
            child: const GoogleMap(
              mapType: MapType.normal,
              initialCameraPosition: _kGooglePlex,
            ),
          ),
          NotificationListener<DraggableScrollableNotification>(
            onNotification: (notification) {
              setState(() {
                // 拖动Sheet时阻止地图响应触摸
                _shouldBlockMap = notification.extentChanged;
              });
              return false; // 允许通知继续传递
            },
            child: DraggableScrollableSheet(
              maxChildSize: 1,
              minChildSize: 0.1,
              initialChildSize: 0.5,
              builder: (context, scrollController) {
                return ListView(
                  controller: scrollController,
                  children: List<Widget>.generate(
                    100,
                    (index) => ColoredBox(
                      color: Colors.white,
                      child: SizedBox(
                        height: 40,
                        child: Text('I am item no. $index'),
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

原理说明

  • DraggableScrollableNotification会在Sheet拖动过程中发送通知,extentChanged字段用于判断当前是否处于拖动状态。
  • IgnorePointer根据ignoring的值决定是否让GoogleMap接收触摸事件,拖动时设为true即可避免地图跟随滚动。
  • 加入kIsWeb判断后,仅Web端会应用该拦截逻辑,Android端的原有正常表现不受影响。

内容的提问来源于stack exchange,提问作者Michael Hathi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:35:05