Flutter地理位置与地图选择插件location_map_picker的使用

Flutter地理位置与地图选择插件location_map_picker的使用

location_map_picker: 一个用于在地图上选择位置的Widget。


开发者

profile

Nasr Al-Rahbi @abom_me


找我

Twitter Instagram LinkedIn Stack Overflow

兼容性

Android iOS Flutter Web
支持 SDK 20+ iOS 9+ 尚未支持

该位置选择器使用了官方的 google_maps_flutter 插件。


设置

Pubspec文件更改:

dependencies:
  map_location_picker: ^0.0.7

示例代码:

import 'package:location_map_picker/location_map_picker.dart';

MapPicker(
  apiKey: "YOUR_API_KEY",
  onPin: (PinData? result) {
    // 处理选择的位置
  },
);

开始使用

  1. Google Cloud平台获取API密钥。
  2. 确保在Google Cloud控制台启用以下API:
    • Android版地图SDK
    • iOS版地图SDK
    • 地点API
    • 编码API
    • 地图JavaScript API
  3. 确保为项目启用计费。

更多详细信息,请参阅Google Maps平台入门指南


Android设置

  1. android/app/build.gradle 中设置 minSdkVersion
android {
    defaultConfig {
        minSdkVersion 20
    }
}

这表示应用将仅适用于运行Android SDK 20或更高版本的用户。

  1. android/app/src/main/AndroidManifest.xml 中指定API密钥:
<manifest ...
  <application ...
    <meta-data android:name="com.google.android.geo.API_KEY"
               android:value="YOUR KEY HERE"/>

混合组件

为了在Android上使用混合组件来渲染 GoogleMap 组件,将 AndroidGoogleMapsFlutter.useAndroidViewSurface 设置为 true

if (defaultTargetPlatform == TargetPlatform.android) {
  AndroidGoogleMapsFlutter.useAndroidViewSurface = true;
}

iOS设置

ios/Runner/AppDelegate.m 中指定API密钥:

#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
#import "GoogleMaps/GoogleMaps.h"

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GMSServices provideAPIKey:@"YOUR KEY HERE"];
  [GeneratedPluginRegistrant registerWithRegistry:self];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end

或者,在Swift代码中,指定API密钥在 ios/Runner/AppDelegate.swift 中:

import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("YOUR KEY HERE")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

注意事项

以下权限不是使用Google Maps Android API v2所必需的,但建议添加:

  • android.permission.ACCESS_COARSE_LOCATION:允许API使用WiFi或移动蜂窝数据(或两者)确定设备的位置。API返回的位置精度大约相当于一个街区。
  • android.permission.ACCESS_FINE_LOCATION:允许API尽可能精确地从可用的位置提供程序(包括全球定位系统(GPS)以及WiFi和移动蜂窝数据)确定位置。

你还需要明确声明你的应用使用 android.hardware.location.networkandroid.hardware.location.gps 硬件特性,如果您的应用针对Android 5.0(API级别21)或更高版本,并且在接收网络或GPS位置更新时使用了 ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION 权限。

<uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />

以下权限在包清单中定义,并在构建时自动合并到您的应用清单中。您不需要显式地将其添加到您的清单中:

  • android.permission.INTERNET:用于API从Google Maps服务器下载地图图块。
  • android.permission.ACCESS_NETWORK_STATE:允许API检查连接状态以确定是否可以下载数据。

MapPicker参数

/// 这里添加起始位置,当进入小部件时会直接出现此位置
/// 如果留空,则会使用默认位置
LatLng? startLocation;

/// 这里输入位于位置选择前显示的文本,可以留空
String? inputText;

/// 这里是提交按钮显示的小部件,可以留空并使用默认发送图标
Widget? sendBtnIcon = const Icon(Icons.send);

/// 这是文本框的文本颜色,默认为黑色
Color? textInputColor;

/// 这是出现在文本框旁边的位置名称图标
Widget? inputIcon;

/// 必须且必须在此处键入Google Cloud的API密钥
final String apiKey;

/// 这是在顶部搜索框中显示的文本,默认为(搜索地点)
String? searchBoxHintText;

/// 这是地图和地点名称的语言,只需输入语言代码
/// 例如:阿拉伯语(ar),英语(en)
/// 可以留空并默认为英语
String? mapLanguage;

/// 这是地图类型,如普通、卫星等
MapType? mapType;

/// 在选择位置后传递的数据,包括地点名称及其LatLng
final void Function(PinData pinData) onPin;

实际示例

Video Example


跟随我

Twitter Instagram LinkedIn Stack Overflow

完整示例代码

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:location_map_picker/location_map_picker.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (builder) => MapPicker(
                      primaryPickerMark: SvgPicture.asset(
                        "assets/icons/pin.svg",
                        width: 40,
                      ),
                      secondaryPickerMark: SvgPicture.asset(
                        "assets/icons/bpin.svg",
                        width: 40,
                      ),
                      onPin: (onPin) {
                        print(onPin.placeName);
                        print(onPin.latLong);
                      },
                      apiKey: 'Your api key',
                    ),
                  ),
                );
              },
              child: Text("Open Map"),
            )
          ],
        ),
      ),
    );
  }
}

更多关于Flutter地理位置与地图选择插件location_map_picker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地理位置与地图选择插件location_map_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,location_map_picker 是一个用于选择地理位置并显示地图的插件。虽然这个具体的插件名称可能不是官方或广泛知名的(因为Flutter生态系统中的插件众多,且名字可能会变化),但我可以提供一个类似的实现思路和代码案例,展示如何在Flutter应用中集成地图和地理位置选择功能。

通常,这类功能可以通过结合 geolocator 插件用于获取设备当前位置,以及 google_maps_flutter 插件用于显示地图和选择位置来实现。以下是一个基本的实现示例:

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加必要的依赖:

dependencies:
  flutter:
    sdk: flutter
  geolocator: ^9.0.2  # 确保使用最新版本
  google_maps_flutter: ^2.1.1  # 确保使用最新版本

2. 获取当前位置

使用 geolocator 插件获取当前位置:

import 'package:geolocator/geolocator.dart';
import 'package:geolocator_platform_interface/geolocator_platform_interface.dart';

Future<Position?> getCurrentLocation() async {
  bool serviceEnabled;
  LocationPermission permission;

  // 检查位置服务是否启用
  serviceEnabled = await Geolocator.isLocationServiceEnabled();
  if (!serviceEnabled) {
    return Future.error('Location services are disabled.');
  }

  permission = await Geolocator.checkPermission();
  if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
    if (permission == LocationPermission.denied) {
      return Future.error('Location permissions are denied');
    }
  }

  if (permission == LocationPermission.deniedForever) {
    // 处理永久拒绝的情况
    return Future.error(
        'Location permissions are permanently denied, we cannot request permissions.');
  }

  // 获取当前位置
  Position position = await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.high);
  return position;
}

3. 显示地图并允许用户选择位置

使用 google_maps_flutter 插件显示地图,并允许用户通过点击地图来选择位置:

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class MapPickerScreen extends StatefulWidget {
  @override
  _MapPickerScreenState createState() => _MapPickerScreenState();
}

class _MapPickerScreenState extends State<MapPickerScreen> {
  late GoogleMapController _controller;
  LatLng? _selectedLocation;
  final Set<Marker> _markers = {};

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Map Picker'),
      ),
      body: GoogleMap(
        mapType: MapType.hybrid,
        initialCameraPosition: CameraPosition(
          target: LatLng(0.0, 0.0), // 初始位置,可以替换为当前位置
          zoom: 14.0,
        ),
        markers: _markers.toSet(),
        onMapCreated: (GoogleMapController controller) {
          _controller = controller;
          // 获取当前位置并移动到该位置
          getCurrentLocation().then((position) {
            if (position != null) {
              _controller.animateCamera(CameraUpdate.newLatLngZoom(
                LatLng(position.latitude, position.longitude),
                14.0,
              ));
            }
          }).catchError((error) {
            print(error);
          });
        },
        onTap: (LatLng latLng) {
          setState(() {
            _markers.clear();
            _markers.add(Marker(
              markerId: MarkerId('selected_location'),
              position: latLng,
              infoWindow: InfoWindow(title: 'Selected Location', snippet: ''),
            ));
            _selectedLocation = latLng;
          });
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 处理选中的位置,例如导航回上一个屏幕并传递位置数据
          Navigator.pop(context, _selectedLocation);
        },
        tooltip: 'Pick Location',
        child: Icon(Icons.check),
      ),
    );
  }
}

4. 使用 MapPickerScreen

在你的应用中,你可以通过导航到 MapPickerScreen 来允许用户选择位置:

void _pickLocation() async {
  LatLng? selectedLocation = await Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => MapPickerScreen()),
  );

  if (selectedLocation != null) {
    // 处理选中的位置
    print('Selected Location: ${selectedLocation!.latitude}, ${selectedLocation!.longitude}');
  }
}

这个示例展示了如何使用 geolocatorgoogle_maps_flutter 插件来实现一个基本的地理位置选择功能。请注意,实际应用中可能需要处理更多的错误情况和用户交互细节。

回到顶部