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

如何用FlutterMap实现带居中固定标记的位置选择器?

用FlutterMap实现中心固定标记的位置选择器

要实现标记始终固定在地图中心、实时显示对应经纬度的位置选择器,核心思路是将标记与地图分离布局,同时监听地图状态变化获取中心坐标。以下是具体实现方案:

1. 配置依赖

在pubspec.yaml中添加所需依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_map: ^6.1.0 # 使用最新稳定版本
  latlong2: ^0.9.0 # 处理经纬度数据

2. 核心实现代码

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';

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

  @override
  State<CenterMarkerPicker> createState() => _CenterMarkerPickerState();
}

class _CenterMarkerPickerState extends State<CenterMarkerPicker> {
  LatLng _currentCenter = const LatLng(39.9042, 116.4074); // 默认初始坐标(北京)
  final MapController _mapController = MapController();

  @override
  void initState() {
    super.initState();
    _currentCenter = _mapController.center;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('位置选择器')),
      body: Stack(
        alignment: Alignment.center,
        children: [
          FlutterMap(
            mapController: _mapController,
            options: MapOptions(
              initialCenter: _currentCenter,
              initialZoom: 14,
              onMapEvent: (MapEvent event) {
                // 监听地图移动、缩放事件,更新中心坐标
                if (event is MapEventMove || event is MapEventZoom) {
                  setState(() {
                    _currentCenter = _mapController.center;
                  });
                }
              },
            ),
            children: [
              TileLayer(
                urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                subdomains: const ['a', 'b', 'c'],
              ),
            ],
          ),
          // 固定在屏幕中心的标记图钉
          const Icon(
            Icons.location_pin,
            color: Colors.red,
            size: 40,
          ),
          // 底部显示实时经纬度的面板
          Positioned(
            bottom: 20,
            left: 16,
            right: 16,
            child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
              decoration: BoxDecoration(
                color: Colors.white.withOpacity(0.9),
                borderRadius: BorderRadius.circular(8),
                boxShadow: const [BoxShadow(blurRadius: 3, color: Colors.black26)],
              ),
              child: Text(
                '当前坐标:\n纬度 ${_currentCenter.latitude.toStringAsFixed(6)},经度 ${_currentCenter.longitude.toStringAsFixed(6)}',
                textAlign: TextAlign.center,
                style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

3. 关键细节说明

  • 固定标记布局:通过Stack组件将标记图标与FlutterMap叠加,设置alignment: Alignment.center让标记始终处于屏幕正中心,完全不受地图移动、缩放的影响,比传统的Marker实现更简洁高效。
  • 实时坐标获取:利用onMapEvent监听地图的移动(MapEventMove)和缩放(MapEventZoom)事件,每次事件触发时通过mapController.center获取最新的地图中心经纬度,调用setState更新显示。
  • 精度控制:使用toStringAsFixed(6)保留6位小数,满足大多数位置选择场景的精度需求,可根据实际需求调整位数。
  • 瓦片替换:示例使用OpenStreetMap的免费瓦片,可替换为高德、谷歌等其他地图服务商的瓦片,只需修改TileLayer的urlTemplate即可(注意遵守对应服务商的使用规则)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:27:36