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

Flutter中基于MapMyIndia实现无密钥地址自动补全搜索方案

Flutter 实现地址自动补全(无MapMyIndia密钥,结合location & geocode依赖)

实现方案

由于无法使用MapMyIndia的SDK/API密钥,我们可以利用已引入的location和geocode包,通过地理编码服务实现地址自动补全效果——核心逻辑是监听用户输入的关键词,调用地理编码接口返回匹配的地址(含经纬度),并展示为可选列表。

1. 确认依赖配置

确保pubspec.yaml中依赖配置正确:

dependencies:
  flutter:
    sdk: flutter
  location: ^5.0.3 # 替换为最新稳定版
  geocode: ^1.0.1 # 替换为最新稳定版

执行flutter pub get完成依赖安装。

2. 获取当前位置(优化搜索精度)

用location包获取设备当前经纬度,作为地址搜索的上下文,缩小匹配范围:

import 'package:location/location.dart';

Future<LocationData?> fetchCurrentLocation() async {
  final location = Location();
  
  // 检查定位服务是否开启
  bool serviceEnabled = await location.serviceEnabled();
  if (!serviceEnabled) {
    serviceEnabled = await location.requestService();
    if (!serviceEnabled) return null;
  }

  // 检查定位权限
  PermissionStatus permission = await location.hasPermission();
  if (permission == PermissionStatus.denied) {
    permission = await location.requestPermission();
    if (permission != PermissionStatus.granted) return null;
  }

  return await location.getLocation();
}

3. 地址自动补全核心逻辑

通过geocode包的正向地理编码能力,根据输入关键词获取匹配地址及经纬度:

import 'package:geocode/geocode.dart';

Future<List<Map<String, dynamic>>> getAddressSuggestions(String query, {LocationData? currentLoc}) async {
  final geoCode = GeoCode();
  final suggestions = <Map<String, dynamic>>[];

  try {
    // 执行正向地理编码查询
    final results = await geoCode.forwardGeocoding(address: query);
    
    // 解析结果,提取地址文本和经纬度
    for (final result in results.results) {
      suggestions.add({
        'address': result.formattedAddress,
        'lat': result.geometry.location.lat,
        'lng': result.geometry.location.lng,
      });
    }
  } catch (e) {
    debugPrint('地址搜索失败: $e');
  }

  return suggestions;
}

4. UI实现搜索框与补全列表

构建带实时搜索功能的UI,展示地址建议列表:

import 'package:flutter/material.dart';

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

  @override
  State<AddressAutoCompletePage> createState() => _AddressAutoCompletePageState();
}

class _AddressAutoCompletePageState extends State<AddressAutoCompletePage> {
  final _searchController = TextEditingController();
  List<Map<String, dynamic>> _suggestions = [];
  LocationData? _currentLocation;

  @override
  void initState() {
    super.initState();
    // 初始化时获取当前位置
    fetchCurrentLocation().then((loc) => setState(() => _currentLocation = loc));
    // 监听输入变化触发搜索
    _searchController.addListener(_handleSearchInputChange);
  }

  void _handleSearchInputChange() {
    final query = _searchController.text.trim();
    if (query.isEmpty) {
      setState(() => _suggestions = []);
      return;
    }

    getAddressSuggestions(query, currentLoc: _currentLocation)
        .then((suggestions) => setState(() => _suggestions = suggestions));
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('地址自动补全')),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16),
            child: TextField(
              controller: _searchController,
              decoration: const InputDecoration(
                hintText: '输入地址关键词',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.search),
              ),
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _suggestions.length,
              itemBuilder: (ctx, idx) {
                final item = _suggestions[idx];
                return ListTile(
                  title: Text(item['address']),
                  subtitle: Text('${item['lat']}, ${item['lng']}'),
                  onTap: () {
                    // 处理地址选中逻辑
                    print('选中地址: ${item['address']}');
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

关键说明

  • 该方案依赖geocode包默认的地理编码服务,若需指定MapMyIndia的地理编码服务,需确认geocode包是否支持自定义服务端点(通常需要配置密钥,不符合需求,因此采用默认服务替代)。
  • 若遇到地理编码服务限制,可添加输入防抖(延迟500ms再发起请求),避免频繁调用接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:35:03