Flutter中实现中国省份地图

效果展示(这里只展示局部,完全展示违规):

可以点击省份改变颜色,更多功能可以自行拓展。

在这里插入图片描述

注:非完整中国地图!!!

本文用于记录在Flutter项目中安卓端实现中国地图,因为实现过程是通过Flutter调用安卓原生代码实现,所以IOS端不可用,通过本文你还可以学会如何通过Platform Channels在Flutter代码中调用这些原生代码。

在Flutter中打开android文件夹

右键android 文件夹,选择flutter -> Open Android module in Android Studio
在这里插入图片描述
点击后就会像打开一个纯Android项目一样(当然还是有些差别的,多了些Flutter相关东西),在这个界面中可以编写原生代码和相应插件。

如果你是第一次打开,它会下载gradle和一大堆构建项目需要的东西,要等好长一会(这个时候你可以买杯咖啡等它构建完成:)),当然过程可能不是那么的顺利,比如你下载gradle过程中会报下面错误(如果没有则忽略下面步骤):

gradle Connect timed out

方法一:

然后我就尝试修改仓库配置为阿里镜像:

allprojects {
    repositories {
        google()
        maven { url "https://jitpack.io" }
        mavenCentral()
        maven { url "https://maven.aliyun.com/repository/public" } //jcenter & central
    }
}

结果还是一样,科学上网打开也一样,此方法无效!

方法二:

https://services.gradle.org/distributions/ 网址中找到你项目中对应的Gradle版本并下载下来。

解压下载的文件并将其放到你的C:/Users/{用户名}/.gradle/wrapper/dists/gradle-{版本号}-all/{随机字符串}目录下。

如果你不确定应该下载哪个版本的Gradle,你可以查看你的Android工程中的gradle/wrapper/gradle-wrapper.properties文件,该文件中的distributionUrl属性就是你需要的Gradle版本。

可能你的.gradle文件夹移到别的地方了,毕竟这个文件夹占用内存太大,正经人谁放C盘 :)

就算是下载超时,本地文件也会创建.gradle/wrapper/dists/gradle-{版本号}-all/{随机字符串}这个目录的。

此时再Build就可以了,接下来就是大量时间去下载其他依赖…

至此Gradle下载问题解决。


不出意外的话接下来你还会遇到这个问题:

Multiple build operations failed.
Could not create task ':flutter_plugin_android_lifecycle:generateDebugUnitTestConfig'.
Could not create task ':image_picker_android:generateDebugUnitTestConfig'.
Could not create task ':path_provider_android:generateDebugUnitTestConfig'.
Could not create task ':shared_preferences_android:generateDebugUnitTestConfig'.
Could not create task ':video_player_android:generateDebugUnitTestConfig'.
Could not create task ':wakelock_plus:generateDebugUnitTestConfig'.
Could not create task ':flutter_plugin_android_lifecycle:generateDebugUnitTestConfig'.
this and base files have different roots: D:\resource\td_ecology_v1\build\flutter_plugin_android_lifecycle and C:\Users\xx\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\flutter_plugin_android_lifecycle-2.0.17\android.

不要慌,解决方法如下:

在文件[flutter项目]\android\build.gradle中,注释掉一行代码就行。

rootProject.buildDir = '../build'
subprojects {
    //project.buildDir = "${rootProject.buildDir}/${project.name}" // 把这行注释掉,在flutter运行的时候,记得取消这行的注释
}
subprojects {
    project.evaluationDependsOn(':app')
}

tasks.register("clean", Delete) {
    delete rootProject.buildDir
}

注释后再Build就可以构建完成了,记得在Flutter运行的时候,记得取消这行的注释哦,不然会报下面错误:

Exception: Gradle build failed to produce an .apk file. It's likely that this file was generated under D:\resource\xxx\build, but the tool couldn't find it.

原生代码编写

核心代码传到了CSDN资源里面,自行下载,不要积分:core文件夹

里面的xml文件要放到 android\app\src\main\res\raw文件夹下奥。

目录如下图所示:

在这里插入图片描述

接下来就是在MainActivity中加入下面代码:

class MainActivity: FlutterActivity() {


    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        GeneratedPluginRegistrant.registerWith(flutterEngine)
        flutterEngine.plugins.add(mutableSetOf<FlutterPlugin>(ChinaProvinceViewFlutterPlugin()))

    }

}

然后返回你的Flutter工程添加下面两个文件:

china_province_view.dart

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

const _ChinaProvinceView_TAG =
    'com.mrper.coronavirus.widgets.china-province-view';

///中国行政区域地图控件
class ChinaProvinceView extends StatefulWidget {

  ChinaProvinceView({
    required this.width,
    required this.onViewCreated,
  })  : assert(width != null && width > 0, '地图宽度必须大于0');

  /// 地图宽度
  final double width;
  /// 视图创建完成的事件
  final Function(int id) onViewCreated;

  
  _ChinaProvinceViewState createState() => _ChinaProvinceViewState();
}

class _ChinaProvinceViewState extends State<ChinaProvinceView> {
  /// 地图的宽高比例
  final double _mapWHRatio = 1369.0 / 1141.0;

  
  Widget build(BuildContext context) => SizedBox(
      width: widget.width,
      height: widget.width / _mapWHRatio,
      child: AndroidView(
          viewType: _ChinaProvinceView_TAG,
          creationParamsCodec: StandardMessageCodec(),
          onPlatformViewCreated: widget.onViewCreated));
}

class ChinaProvinceViewController {
  late MethodChannel? _methodChannel;
  late EventChannel? _eventChannel;

  ChinaProvinceViewController(int viewId) {
    _methodChannel = MethodChannel('$_ChinaProvinceView_TAG-$viewId');
    _eventChannel = EventChannel('$_ChinaProvinceView_TAG-$viewId-event');
  }

  /// 设置选中的背景色
  set selectedBackgroundColor(int value) => _methodChannel?.invokeMethod(
      'setSelectedBackgroundColor', {'value': value ?? Colors.red.value});

  

  void dispose() {
    if (_methodChannel != null) {
      _methodChannel?.setMethodCallHandler(null);
      _methodChannel = null;
    }
    if (_eventChannel != null) {
      _eventChannel = null;
    }
  }
}

map_page.dart


import 'package:ecology/component/app_bar.dart';
import 'package:flutter/material.dart';

import 'china_province_view.dart';

class MapPage extends StatefulWidget {

  
  _MapPageState createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> {
  late ChinaProvinceViewController _chinaProvinceViewController;

  void _onChinaProvinceViewCreated(int viewId) {
    _chinaProvinceViewController = ChinaProvinceViewController(viewId)
      ..selectedBackgroundColor = Colors.blue.value;
  }

  
  Widget build(BuildContext context) => Container(
    child: SingleChildScrollView(
        child: Column(children: [_buildChinaMapView()])),
  );

  Widget _buildChinaMapView() {
    return Container(
        margin: const EdgeInsets.all(5),
        child: ChinaProvinceView(
            width: MediaQuery.of(context).size.width - 10,
            onViewCreated: _onChinaProvinceViewCreated));
  }

  
  void dispose() {
    _chinaProvinceViewController?.dispose();
    super.dispose();
  }
}

MapPage 就是地图界面了。

打完收工,又是加班的一天 ┭┮﹏┭┮


该篇文章代码参考自gitee上一个大佬的项目:https://gitee.com/yugecse/coronavirus

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现类似微信发送定位的功能,你需要使用百度地图提供的 SDK。在 Flutter ,你可以使用 `flutter_baidu_mapapi_sdk` 插件来使用百度地图 SDK。 下面是实现类似微信发送定位的步骤: 1. 引入插件 在 `pubspec.yaml` 文件添加 `flutter_baidu_mapapi_sdk` 插件依赖: ```yaml dependencies: flutter_baidu_mapapi_sdk: ^latest_version ``` 2. 初始化地图 在需要使用地图的页面初始化地图,可以使用 `BaiduMapController` 控制地图: ```dart import 'package:flutter_baidu_mapapi_sdk/flutter_baidu_mapapi_sdk.dart'; class MapPage extends StatefulWidget { @override _MapPageState createState() => _MapPageState(); } class _MapPageState extends State<MapPage> { BaiduMapController _controller; @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ BaiduMap( onMapCreated: (controller) { _controller = controller; }, initialCameraPosition: CameraPosition( target: LatLng(39.915, 116.404), zoom: 11, ), ), ], ), ); } } ``` 3. 添加定位按钮 在页面添加一个定位按钮,当用户点击按钮时,获取当前位置信息并显示在地图上: ```dart import 'package:location/location.dart'; class _MapPageState extends State<MapPage> { ... final _location = Location(); void _getCurrentLocation() async { final locationData = await _location.getLocation(); final latLng = LatLng(locationData.latitude, locationData.longitude); _controller.animateCamera(CameraUpdate.newLatLng(latLng)); _controller.addMarker(MarkerOptions( position: latLng, icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed), )); } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ BaiduMap( onMapCreated: (controller) { _controller = controller; }, initialCameraPosition: CameraPosition( target: LatLng(39.915, 116.404), zoom: 11, ), ), Positioned( bottom: 16, right: 16, child: FloatingActionButton( onPressed: _getCurrentLocation, child: Icon(Icons.location_on), ), ), ], ), ); } } ``` 4. 获取地址信息 通过百度地图提供的 `ReverseGeoCodeSearch` 类,可以根据经纬度获取地址信息: ```dart import 'package:flutter_baidu_mapapi_sdk/flutter_baidu_mapapi_sdk.dart'; class _MapPageState extends State<MapPage> { ... final _location = Location(); final _search = ReverseGeoCodeSearch(); void _getCurrentLocation() async { final locationData = await _location.getLocation(); final latLng = LatLng(locationData.latitude, locationData.longitude); _controller.animateCamera(CameraUpdate.newLatLng(latLng)); _controller.addMarker(MarkerOptions( position: latLng, icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed), )); _search.reverseGeoCode( ReverseGeoCodeOption( location: latLng, ), onGetReverseGeoCodeResult: (result) { final address = result.address; print(address); }, ); } ... } ``` 5. 发送位置信息 最后,你可以通过你的应用程序向服务器发送位置信息,实现类似微信发送位置的功能。 以上就是实现类似微信发送定位的步骤,你可以根据你的具体需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值