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

如何在Flutter Syncfusion Map中编程移动Marker至目标MapLatLng

实现Syncfusion Flutter Map中蓝色Marker向红色目标Marker的平滑移动效果

核心思路

通过Flutter的AnimationController和Tween对经纬度进行插值计算,实时更新蓝色Marker的位置,模拟行进的平滑动画效果。因为Syncfusion的MapLatLng是不可变类,需要自定义插值逻辑来实现经纬度的逐步过渡。


步骤实现

1. 基础状态与动画初始化

在State类中定义必要的变量,包括当前位置、目标位置、动画控制器以及经纬度的动画插值对象:

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';

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

  @override
  State<MapMarkerMovementDemo> createState() => _MapMarkerMovementDemoState();
}

class _MapMarkerMovementDemoState extends State<MapMarkerMovementDemo> with SingleTickerProviderStateMixin {
  // 初始蓝色Marker位置(模拟用户当前位置)
  late MapLatLng _currentPosition;
  // 红色目标Marker位置
  MapLatLng? _targetPosition;
  // 动画控制器
  late AnimationController _animationController;
  // 纬度、经度的动画插值
  late Animation<double> _latAnimation;
  late Animation<double> _lngAnimation;

  @override
  void initState() {
    super.initState();
    // 初始化模拟位置(示例为北京天安门附近)
    _currentPosition = const MapLatLng(39.9042, 116.4074);
    // 初始化动画控制器,时长设为3秒(可按需调整)
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 3),
    );
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }
}

2. 处理地图点击事件,触发移动动画

为SfMaps添加onTap回调,获取用户点击的经纬度作为目标位置,然后初始化并启动动画:

// 用户点击地图时触发
void _onMapTap(MapLatLng tappedPosition) {
  setState(() {
    _targetPosition = tappedPosition;
  });

  // 重置动画避免冲突
  _animationController.reset();
  // 创建纬度、经度的Tween插值
  _latAnimation = Tween<double>(
    begin: _currentPosition.latitude,
    end: _targetPosition!.latitude,
  ).animate(CurvedAnimation(parent: _animationController, curve: Curves.easeInOut));
  _lngAnimation = Tween<double>(
    begin: _currentPosition.longitude,
    end: _targetPosition!.longitude,
  ).animate(CurvedAnimation(parent: _animationController, curve: Curves.easeInOut));

  // 监听动画更新,实时刷新当前位置
  _animationController.addListener(() {
    setState(() {
      _currentPosition = MapLatLng(
        _latAnimation.value,
        _lngAnimation.value,
      );
    });
  });

  // 动画结束后,将当前位置固定到目标位置
  _animationController.addStatusListener((status) {
    if (status == AnimationStatus.completed) {
      setState(() {
        _currentPosition = _targetPosition!;
      });
    }
  });

  _animationController.forward();
}

3. 构建带Marker的地图UI

在build方法中创建SfMaps组件,添加MarkerLayer渲染蓝色当前位置Marker和红色目标Marker:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('Marker Movement Demo')),
    body: SfMaps(
      layers: [
        MapTileLayer(
          urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
          initialZoomLevel: 14,
          initialFocalLatLng: _currentPosition,
          onTap: _onMapTap,
          markerBuilder: (BuildContext context, int index) {
            final markers = <MapMarker>[];
            // 添加蓝色当前位置Marker
            markers.add(MapMarker(
              latitude: _currentPosition.latitude,
              longitude: _currentPosition.longitude,
              child: const Icon(Icons.location_on, color: Colors.blue, size: 30),
            ));
            // 有目标位置时添加红色目标Marker
            if (_targetPosition != null) {
              markers.add(MapMarker(
                latitude: _targetPosition!.latitude,
                longitude: _targetPosition!.longitude,
                child: const Icon(Icons.location_pin, color: Colors.red, size: 30),
              ));
            }
            return markers[index];
          },
          markerCount: _targetPosition != null ? 2 : 1,
        ),
      ],
    ),
  );
}

关键细节说明

  • 动画曲线:使用Curves.easeInOut实现自然的加速减速效果,替换为Curves.linear可实现匀速移动。
  • 速度调整:修改AnimationController的duration参数可控制移动快慢。
  • 重复点击处理:每次点击前调用_animationController.reset(),避免动画叠加冲突。
  • 地图瓦片:示例使用OpenStreetMap瓦片,可替换为Syncfusion支持的其他地图服务瓦片。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:45:31