【Flutter】使用高德地图实现地图选点以及地图搜索

效果

插件安装以及环境配置

是使用amap_all_fluttify插件来完成的高德地图的集成

【Flutter】使用高德地图实现地图选点以及地图搜索_第1张图片

根据官方的说明,这个插件集成了amap_search_fluttify,amap_location_fluttify,amap_map_fluttify.这些插件。

安装amap_all_fluttify 插件后,还需要根据每个插件进行配置。

例如amap_search_fluttify

【Flutter】使用高德地图实现地图选点以及地图搜索_第2张图片

【Flutter】使用高德地图实现地图选点以及地图搜索_第3张图片

按照官方文档进行配置即可。

之后就可以尝试进行运行,但是这时会出现一个报错:

Error:The number of method references in a .dex file cannot exceed 64K.

我才用的解决办法才用的是 https://blog.csdn.net/nakajimafn/article/details/82668793 这个链接对应的第二个方法。

代码编写

文档结构

【Flutter】使用高德地图实现地图选点以及地图搜索_第4张图片

main.dart

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

import 'components/map_choicePoint.dart';

Future main() async {
  runApp(MyApp());
  //地图基本功能-注册高德key
  await AmapService.init(androidKey: '');
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AMAP_Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'AMAP_Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(child: MapChoicePoint((point) {
        debugPrint(point.toString());
      })),
    );
  }
}

map_choicePoint.dart

import 'package:flutter/material.dart';
import 'package:amap_all_fluttify/amap_all_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';

/**
 * 地图选择点控件
 */
class MapChoicePoint extends StatefulWidget {
  /**
   * 选择点后回调事件
   */
  final Function onChoicePoint;
  MapChoicePoint(this.onChoicePoint);
  @override
  _MapChoicePointState createState() => _MapChoicePointState();
}

class _MapChoicePointState extends State
    with SingleTickerProviderStateMixin {
  //----属性----

  //地图控制器
  AmapController _amapController;
  //选择的点
  Marker _markerSelect;
  //搜索出来之后选择的点
  Marker _markerSeached;
  //所在城市
  String city;
  //搜索框文字控制器
  TextEditingController _serachController;
  //自定义marker点图标图片路径
  Uri _imgUri = Uri.parse('images/position.png');

  //----方法----

  /**
   * 获取权限
   */
  Future _requestPermission() async {
    final permissions = await PermissionHandler()
        .requestPermissions([PermissionGroup.location]);
    if (permissions[PermissionGroup.location] == PermissionStatus.granted) {
      return true;
    } else {
      toast('需要定位权限!');
      return false;
    }
  }

  /**
   * 根据搜索条件选出想要的点
   */
  Future _openModalBottomSheet() async {
    //收起键盘
    FocusScope.of(context).requestFocus(FocusNode());
    //根据关键字及城市进行搜索
    final poiList = await AmapSearch.searchKeyword(
      _serachController.text,
      city: city,
    );
    List points = [];
    //便利拼接信息
    for (var item in poiList) {
      points.add({
        'title': await item.title,
        'address': await item.adName + await item.address,
        'position': await item.latLng,
      });
    }
    //弹出底部对话框并等待选择
    final option = await showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return points.length > 0
              ? ListView.builder(
                  itemCount: points.length,
                  itemBuilder: (BuildContext itemContext, int i) {
                    return ListTile(
                      title: Text(points[i]['title']),
                      subtitle: Text(points[i]['address']),
                      onTap: () {
                        Navigator.pop(context, points[i]);
                      },
                    );
                  },
                )
              : Container(
                  alignment: Alignment.center,
                  padding: EdgeInsets.all(40),
                  child: Text('暂无数据'));
        });

    if (option != null) {
      LatLng selectlatlng = option['position'];
      //将地图中心点移动到选择的点
      _amapController.setCenterCoordinate(
          selectlatlng.latitude, selectlatlng.longitude);
      //删除原来地图上搜索出来的点
      if (_markerSeached != null) {
        _markerSeached.remove();
      }
      //将搜索出来的点显示在界面上 --此处不能使用自定义图标的marker,使用会报错,至今也没有解决
      _markerSeached = await _amapController.addMarker(MarkerOption(
        latLng: selectlatlng,
      ));
    }
  }

  @override
  void initState() {
    super.initState();
    _serachController = TextEditingController();
  }

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

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: AlignmentDirectional.topCenter,
      children: [
        AmapView(
          // 地图类型 (可选)
          mapType: MapType.Standard,
          // 是否显示缩放控件 (可选)
          showZoomControl: true,
          // 是否显示指南针控件 (可选)
          showCompass: false,
          // 是否显示比例尺控件 (可选)
          showScaleControl: true,
          // 是否使能缩放手势 (可选)
          zoomGesturesEnabled: true,
          // 是否使能滚动手势 (可选)
          scrollGesturesEnabled: true,
          // 是否使能旋转手势 (可选)
          rotateGestureEnabled: false,
          // 是否使能倾斜手势 (可选)
          tiltGestureEnabled: false,
          // 缩放级别 (可选)
          zoomLevel: 16,
          // 中心点坐标 (可选)
          // centerCoordinate: LatLng(39, 116),
          // 标记 (可选)
          markers: [],
          // 标识点击回调 (可选)
          onMarkerClicked: (Marker marker) async {
            if (_markerSeached == null) {
              return;
            }
            //获取点击点的位置
            var location = await marker.location;
            var lon = location.longitude;
            var lat = location.latitude;
            //获取搜索点的位置
            var slocation = await _markerSeached.location;
            var slon = slocation.longitude;
            var slat = slocation.latitude;
            //比较位置
            if (lon == slon && lat == slat) {
              //移除原来的点
              if (_markerSeached != null) {
                _markerSeached.remove();
              }
              if (_markerSelect != null) {
                _markerSelect.remove();
              }
              //画上新的点
              _markerSelect = await _amapController.addMarker(MarkerOption(
                  latLng: location,
                  iconUri: _imgUri,
                  imageConfig: createLocalImageConfiguration(context),
                  width: 64,
                  height: 64,
                  anchorV: 0.7,
                  anchorU: 0.5));
            }
          },
          // 地图点击回调 (可选)
          onMapClicked: (LatLng coord) async {
            
            if (_amapController != null) {
              //移除原来的点
              if (_markerSelect != null) {
                _markerSelect.remove();
              }
              if (_markerSeached != null) {
                _markerSeached.remove();
              }
              //画上新的点
              _markerSelect = await _amapController.addMarker(MarkerOption(
                  latLng: coord,
                  iconUri: _imgUri,
                  imageConfig: createLocalImageConfiguration(context),
                  width: 64,
                  height: 64,
                  anchorV: 0.7,
                  anchorU: 0.5));
              widget.onChoicePoint(coord);
            }
          },
          onMapMoveStart: (MapMove move) {},
          // 地图创建完成回调 (可选)
          onMapCreated: (controller) async {
            _amapController = controller;
            //申请权限
            if (await _requestPermission()) {
              //获取所在城市
              final location = await AmapLocation.fetchLocation();        
              city = await location.city;
              //显示自己的定位
              await controller.showMyLocation(MyLocationOption(show: true));
              // await initSerach();
            }
          },
        ),
        Container(
          margin: EdgeInsets.all(20),
          width: MediaQuery.of(context).size.width,
          height: 46,
          decoration: BoxDecoration(color: Colors.white),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Container(
                padding: EdgeInsets.all(8),
                width: MediaQuery.of(context).size.width - 20 - 80,
                child: TextField(
                  controller: _serachController,
                  decoration: InputDecoration(border: InputBorder.none),
                  inputFormatters: [
                    LengthLimitingTextInputFormatter(10) //限制长度
                  ],
                ),
              ),
              IconButton(
                  icon: Icon(Icons.search), onPressed: _openModalBottomSheet)
            ],
          ),
        )
      ],
    );
  }
}

 

 

 

你可能感兴趣的:(Flutter)