flutter 高德地图选择位置信息返回

添加依赖:(注意,作者一直更新维护,请以最新的版本添加)

  amap_map_fluttify: ^0.10.2
  amap_search_fluttify: ^0.3.4
/// !!使用真机调试!!
/// !注意: 只要是返回Future的方法, 一律使用`await`修饰, 确保当前方法执行完成后再执行下一行, 在不能使用`await`修饰的环境下, 在`then`方法中执行下一步.
/// 
/// Swift工程需要注释掉Podfile中的`use_frameworks!`
/// 初始化:
///   1. iOS在init方法中设置
///   2. Android需要在AndroidManifest.xml里去设置, 详见 https://lbs.amap.com/api/android-sdk/gettingstarted
///     <application>
///       <meta-data
///         android:name="com.amap.api.v2.apikey"
///         android:value="您的Key"/>
///     </application>
await AmapCore.init('key');
/// 如果你觉得引擎的日志太多, 可以关闭Fluttify引擎的日志
await enableFluttifyLog(false); // 关闭log

 

代码实现:

import 'package:amap_map_fluttify/amap_map_fluttify.dart';

import 'package:flutter/material.dart';
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:demo/resources/custom_text_style.dart';
import 'package:demo/utils/misc.dart';

import 'package:demo/widgets/network_state/page_loading.dart';

class SelectLocationFromMapPage extends StatefulWidget {
  @override
  _SelectLocationFromMapPageState createState() =>
      _SelectLocationFromMapPageState();
}

class _SelectLocationFromMapPageState extends State<SelectLocationFromMapPage> {
  AmapController _controller;
  List<Poi> poiList;
  static List<PoiModel> list = new List();
  static List<PoiModel> searchlist = new List();
  PoiModel poiModel;
  String keyword = "";
  String address = "";
  bool isloading = true;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomPadding: false, //防止底部布局被顶起
      appBar: AppBar(
        title: Text(
          '选择位置信息',
          style: CustomTextStyle.appBarTitleTextStyle,
        ),
        elevation: 0.0,
        centerTitle: true,
      ),

      body: Column(
        children: <Widget>[
          Theme(
            data: new ThemeData(
                primaryColor: Color(0xFFFFCA28), hintColor: Color(0xFFFFCA28)),
            child: Container(
              color: Color(0xFFFFCA28),
              padding: EdgeInsets.all(5),
              child: Container(
                height: 36,
                margin: EdgeInsets.only(left: 5, right: 5, bottom: 5),
                child: TextField(
                  style: TextStyle(fontSize: 16, letterSpacing: 1.0),
                  controller: TextEditingController.fromValue(TextEditingValue(
                    // 设置内容
                    text: keyword,
                    selection: TextSelection.fromPosition(TextPosition(
                        affinity: TextAffinity.downstream,
                        offset: keyword?.length ?? 0)),
                    // 保持光标在最后
                  )),
                  decoration: InputDecoration(
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(40)),
                    ),
                    hintText: '输入关键字',
                    hintStyle:
                        TextStyle(color: Color(0xFFBEBEBE), fontSize: 14),
                    contentPadding:
                        const EdgeInsets.symmetric(vertical: 8, horizontal: 1),
                    prefixIcon: Icon(
                      Icons.search,
                      color: Colors.grey,
                      size: 20,
                    ),
                    suffixIcon: IconButton(
                      icon: Icon(
                        Icons.clear,
                        color: Colors.grey,
                        size: 20,
                      ),
                      onPressed: () {
                        keyword = "";
                        setState(() {});
                      },
                    ),
                    fillColor: Colors.white,
                    filled: true,
                  ),

                  inputFormatters: [],
                  //内容改变的回调
                  onChanged: (text) {
                    print('change $text');
                    keyword = text;
                  },
                  //内容提交(按回车)的回调
                  onSubmitted: (text) {
                    print('submit $text');
                    // 触发关闭弹出来的键盘。
                    keyword = text;
                    setState(() {
                      isloading = true;
                      FocusScope.of(context).requestFocus(FocusNode());
                    });

                    searchAroundAddress(text.toString());
                  },
                  //按回车时调用
                  onEditingComplete: () {
                    print('onEditingComplete');
                  },
                ),
              ),
            ),
          ),
          Container(
            height: 300,
            child: Stack(
              children: <Widget>[
                AmapView(
                  showZoomControl: false,
                  centerCoordinate: LatLng(39, 110),
                  maskDelay: Duration(milliseconds: 500),
                  zoomLevel: 16,
                  onMapCreated: (controller) async {
                    _controller = controller;
                    if (await requestPermission()) {
                      await controller.showMyLocation(true);
                      await controller?.showLocateControl(true);
                      final latLng = await _controller?.getLocation(
                          delay: Duration(seconds: 2));
                      await enableFluttifyLog(false); // 关闭log
                      _loadData(latLng);
                    }
                  },
                  onMapMoveEnd: (MapMove move) async {
                    _loadData(move.latLng);
                  },
                ),
                Center(
                  child: Icon(
                    Icons.place,
                    size: 36.0,
                    color: Color(0xFFFF0000),
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            flex: 1,
            child: Visibility(
              visible: !isloading,
              maintainSize: false,
              maintainSemantics: false,
              maintainInteractivity: false,
              replacement: PageLoading(),
              child: ListView.builder(
                  itemCount: list.length,
                  itemBuilder: (BuildContext context, int position) {
                    print("itemBuilder" + list.length.toString());
                    PoiModel item = list[position];
                    return InkWell(
                      child: Column(
                        children: <Widget>[
                          Container(
                            margin:
                                EdgeInsets.only(top: 8, bottom: 5, left: 10),
                            child: Row(
                              children: <Widget>[
                                Icon(
                                  Icons.place,
                                  size: 20.0,
                                  color: position == 0
                                      ? Colors.green
                                      : Colors.grey,
                                ),
                                Text(item.title,
                                    style: TextStyle(
                                        fontSize: 16,
                                        color: position == 0
                                            ? Colors.green
                                            : Color(0xFF787878)))
                              ],
                            ),
                          ),
                          Container(
                            margin:
                                EdgeInsets.only(top: 5, bottom: 5, left: 18),
                            alignment: Alignment.centerLeft,
                            child: Text(
                              item.address,
                              style: TextStyle(
                                fontSize: 14,
                                color: Color(0xFF646464),
                              ),
                            ),
                          ),
                          Divider(
                            height: 1,
                          )
                        ],
                      ),
                      onTap: () async {
                        await _controller.setCenterCoordinate(
                            item.latLng.latitude, item.latLng.longitude,
                            zoomLevel: 16);
                        Navigator.pop(context, {
                          'address': item.address,
                        });
                      },
                    );
                  }),
            ),
          ),
        ],
      ),
    );
  }

  void _loadData(LatLng latLng) async {
    setState(() {
      isloading = true;
    });

    /// 逆地理编码(坐标转地址)
    ReGeocode reGeocodeList = await AmapSearch.searchReGeocode(
      latLng,
    );

    print(await reGeocodeList.toFutureString());
    address = await reGeocodeList.formatAddress;


    final poiList = await AmapSearch.searchKeyword(
      address.toString(),
      city: "西安",
    );

    poiModel = new PoiModel("当前位置", address, latLng);
    list.clear();
    list.add(poiModel);
    for (var poi in poiList) {
      String title = await poi.title;
      String cityName = await poi.cityName;
      String provinceName = await poi.provinceName;
      String address = await poi.address;
      LatLng latLng = await poi.latLng;

      list.add(new PoiModel(
          title.toString(),
          provinceName.toString() + cityName.toString() + address.toString(),
          latLng));
    }

    setState(() {
      isloading = false;
    });
  }

  void searchAroundAddress(String text) async {
    final poiList = await AmapSearch.searchKeyword(
      text,
      city: "西安",
    );

    list.clear();
    list.add(poiModel);
    for (var poi in poiList) {
      String title = await poi.title;
      LatLng latLng = await poi.latLng;
      String cityName = await poi.cityName;
      String provinceName = await poi.provinceName;
      String address = await poi.address;
      list.add(new PoiModel(
          title.toString(),
          provinceName.toString() + cityName.toString() + address.toString(),
          latLng));
    }
    setState(() {
      isloading = false;
      FocusScope.of(context).requestFocus(FocusNode());
    });
  }
}

class PoiModel {
  LatLng latLng;
  String title;
  String address;

  PoiModel(this.title, this.address, this.latLng);
}

misc.dart

import 'package:permission_handler/permission_handler.dart';

Future<bool> requestPermission() async {
  final permissions =
      await PermissionHandler().requestPermissions([PermissionGroup.location]);

  if (permissions[PermissionGroup.location] == PermissionStatus.granted) {
    return true;
  } else {
    ToastUtils.toastLong("需要定位权限!");
    return false;
  }
}

pageloading.dart

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

class PageLoading extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          CupertinoActivityIndicator(),
//          Text('  正在加载', style: TextStyle(fontSize: 16.0),),
        ],
      ),
    );
  }
}

效果:

posted on 2019-12-07 19:01  LoaderMan  阅读(3631)  评论(2编辑  收藏  举报

导航