Flutter for OpenHarmony 地图功能萌系实战指南:给 App 加上超萌 “小地图”✨
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
一、开篇:给鸿蒙 App 装个 “超萌小地图”
哈喽~这次我给 Flutter 鸿蒙 App 装上了一个软乎乎的小地图!就像给 App 配了个会发光的 “导航小助手”,不仅能显示用户位置,还能缩放地图、打可爱的小标记,用起来超治愈~
这次的小项目里,我搞定了这几件大事:
给鸿蒙 App 集成了flutter_map地图库,适配了鸿蒙系统的渲染机制
申请了位置权限,让地图能找到用户的当前位置,点个粉粉的小标记
调通了地图缩放和标记功能,拖动、放大缩小都丝滑不卡顿
接下来就和我一起看看,怎么给鸿蒙 App 装上这个超萌小地图吧~
二、第一步:集成地图库,给 App 装个 “地图引擎”🗺️
要实现地图功能,首先得给 App 装个 “地图引擎”~我选了和开源鸿蒙兼容性超棒的flutter_map,它不用依赖原生地图 SDK,纯 Dart 实现的,适配起来超省心!
一开始集成的时候,我踩了个小坑:鸿蒙设备上地图瓦片加载不出来,像被雾遮住了一样~后来才发现,是网络权限没开!给 App 加上ohos.permission.INTERNET权限后,瓦片一下子就加载出来了,地图瞬间变得清清爽爽的~

pubspec.yaml 依赖配置
yaml
name: flutter_ohos_map_cute
description: 鸿蒙萌系地图实战
version: 1.0.0+1

environment:
  sdk: '>=3.0.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  flutter_map: ^6.1.0
  latlong2: ^0.9.0
鸿蒙权限配置(module.json5)
json
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET",
        "reason": "$string:internet_permission",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.LOCATION",
        "reason": "$string:location_permission",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        }
      }
    ]
  }
}

三、第二步:申请位置权限,让地图找到你📍
地图最可爱的功能,就是能找到用户的位置,点个粉粉的小标记~不过鸿蒙系统对位置权限管得很严,要先申请权限,地图才能乖乖定位哦!
我给 App 加了个权限申请逻辑:打开地图页面时,会弹出一个软乎乎的提示,问用户 “可以让小地图找到你吗?”,用户同意后,地图就会显示当前位置,点上一个粉粉的小标记,像给用户的位置盖了个可爱的章~
位置权限与定位核心代码

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

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

  
  State<CuteMapPage> createState() => _CuteMapPageState();
}

class _CuteMapPageState extends State<CuteMapPage> {
  // 默认位置(示例)
  LatLng _currentLocation = const LatLng(31.82, 117.23);
  bool _permissionGranted = false;

  
  void initState() {
    super.initState();
    _requestLocationPermission();
  }

  // 鸿蒙适配:位置权限申请(简化示例)
  Future<void> _requestLocationPermission() async {
    // 实际项目中可配合 permission_handler 库实现
    setState(() {
      _permissionGranted = true;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('超萌小地图 🗺️')),
      body: _permissionGranted
          ? FlutterMap(
              options: MapOptions(
                initialCenter: _currentLocation,
                initialZoom: 13,
                minZoom: 8,
                maxZoom: 18,
              ),
              children: [
                // 地图瓦片层(鸿蒙适配:使用开源瓦片服务)
                TileLayer(
                  urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                  userAgentPackageName: 'com.example.map',
                ),
                // 位置标记(超萌粉色标记)
                MarkerLayer(
                  markers: [
                    Marker(
                      point: _currentLocation,
                      builder: (context) => const Icon(
                        Icons.location_on,
                        color: Colors.pink,
                        size: 36,
                      ),
                    ),
                  ],
                ),
              ],
            )
          : const Center(child: Text('请先允许位置权限,让小地图找到你哦~')),
    );
  }
}

四、第三步:地图缩放与标记,给地图加上可爱细节✨
地图光显示位置还不够,我还给它加了缩放和标记功能~用户可以用手指放大缩小地图,像在玩一个软软的地球仪;还能在地图上点一下,就会出现一个粉粉的小标记,像给喜欢的位置盖个可爱的章~
适配的时候我发现,鸿蒙设备上地图缩放有时候会有点卡顿,后来给地图加了RepaintBoundary,像给地图单独开了个小房间,渲染一下子就丝滑了!还有标记的大小也调了一下,太大的标记会挡住地图,小小的粉点刚刚好,可爱又不碍事~
带缩放控制与标记的完整代码

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

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

  
  State<CuteMapPage> createState() => _CuteMapPageState();
}

class _CuteMapPageState extends State<CuteMapPage> {
  final MapController _mapController = MapController();
  LatLng _currentLocation = const LatLng(31.82, 117.23);
  final List<Marker> _markers = [];

  
  void initState() {
    super.initState();
    // 添加默认位置标记
    _markers.add(Marker(
      point: _currentLocation,
      builder: (context) => const Icon(
        Icons.location_on,
        color: Colors.pink,
        size: 36,
      ),
    ));
  }

  // 点击地图添加标记
  void _addMarker(TapPosition tapPosition, LatLng point) {
    setState(() {
      _markers.add(Marker(
        point: point,
        builder: (context) => const Icon(
          Icons.favorite,
          color: Colors.pinkAccent,
          size: 24,
        ),
      ));
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('超萌小地图 🗺️')),
      body: Column(
        children: [
          // 鸿蒙优化:地图加独立重绘区域,不卡顿
          Expanded(
            child: RepaintBoundary(
              child: FlutterMap(
                mapController: _mapController,
                options: MapOptions(
                  initialCenter: _currentLocation,
                  initialZoom: 13,
                  minZoom: 8,
                  maxZoom: 18,
                  onTap: _addMarker,
                ),
                children: [
                  TileLayer(
                    urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                    userAgentPackageName: 'com.example.map',
                  ),
                  MarkerLayer(markers: _markers),
                ],
              ),
            ),
          ),
          // 缩放控制按钮
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                IconButton(
                  onPressed: () => _mapController.move(_mapController.center, _mapController.zoom - 1),
                  icon: const Icon(Icons.remove_circle, color: Colors.pink, size: 32),
                ),
                const SizedBox(width: 20),
                IconButton(
                  onPressed: () => _mapController.move(_mapController.center, _mapController.zoom + 1),
                  icon: const Icon(Icons.add_circle, color: Colors.pink, size: 32),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

五、真机验证:小地图在鸿蒙设备上跑起来啦!🎉
我把地图功能装到鸿蒙真机上跑了一下,效果超棒:
地图瓦片加载很快,没有卡顿,就像在看一张会动的粉粉地图
位置标记稳稳地显示在当前位置,粉粉的图标超可爱
缩放地图的时候丝滑不卡顿,点一下地图还能加小爱心标记,像在地图上写小秘密~
不过一开始也踩了个小坑:鸿蒙设备上有时候瓦片加载会慢一点,后来换了国内的瓦片镜像,加载速度一下子就变快了!
这是我的运行截图:在这里插入图片描述

六、复盘与小技巧分享💡
折腾完这个小地图,我也总结了几个鸿蒙地图适配的小技巧:
选对地图库:flutter_map纯 Dart 实现,不用依赖原生 SDK,和开源鸿蒙兼容性超棒
权限要开全:INTERNET和LOCATION权限都要开,不然瓦片加载不出来,也没法定位
优化渲染性能:给地图加RepaintBoundary,减少重绘,鸿蒙设备上更丝滑
瓦片服务选稳定的:用国内镜像的瓦片服务,加载速度更快,不容易卡住
七、结尾:超萌小地图谁不爱呀~
这次给鸿蒙 App 装上的超萌小地图,不仅实用还超可爱!看着粉粉的标记和丝滑的地图,用起来心情都变好了~

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐