select_address_page.dart 10.3 KB
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:Parlando/widgets/my_button.dart';
import 'package:Parlando/widgets/search_bar.dart';
import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart';
import 'package:flutter_baidu_mapapi_map/flutter_baidu_mapapi_map.dart';
import 'package:flutter_baidu_mapapi_search/flutter_baidu_mapapi_search.dart';
import 'package:flutter_bmflocation/flutter_bmflocation.dart';
import 'package:getwidget/getwidget.dart';

import '../../routers/fluro_navigator.dart';
import '../../util/toast_utils.dart';

class AddressSelectPage extends StatefulWidget {
  const AddressSelectPage({Key? key}) : super(key: key);

  @override
  AddressSelectPageState createState() => AddressSelectPageState();
}

class AddressSelectPageState extends State<AddressSelectPage> {
  List<BMFSuggestionInfo> _list = [];
  int _index = 0;
  final ScrollController _controller = ScrollController();
  late BMFMapController _myMapController;
  BaiduLocation _locationResult = BaiduLocation();
  LocationFlutterPlugin myLocPlugin = LocationFlutterPlugin();
  bool isLoading = false;

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

  @override
  void initState() {
    super.initState();
    myLocPlugin.setAgreePrivacy(true);
    // 百度地图sdk初始化鉴权
    if (Platform.isIOS) {
      myLocPlugin.authAK('rMsgMvYERM9zHDDdaipk34oBx7yoaGQh');
      BMFMapSDK.setApiKeyAndCoordType(
          'rMsgMvYERM9zHDDdaipk34oBx7yoaGQh', BMF_COORD_TYPE.BD09LL);

      ///接受定位回调
      myLocPlugin.singleLocationCallback(callback: (BaiduLocation result) {
        setState(() {
          _locationResult = result;
          locationFinish();
        });
      });
    } else if (Platform.isAndroid) {
      // Android 目前不支持接口设置Apikey,
      // 请在主工程的Manifest文件里设置,详细配置方法请参考官网(https://lbsyun.baidu.com/)demo
      BMFMapSDK.setCoordType(BMF_COORD_TYPE.BD09LL);
      myLocPlugin.seriesLocationCallback(callback: (BaiduLocation result) {
        setState(() {
          _locationResult = result;

          locationFinish();
          myLocPlugin.stopLocation();
        });
      });
    }

    ///设置定位参数
    _locationAction();
    _startLocation();
  }

  void _locationAction() async {
    Map iosMap = initIOSOptions().getMap();
    Map androidMap = initAndroidOptions().getMap();

    await myLocPlugin.prepareLoc(androidMap, iosMap);
  }

  ///定位完成添加mark
  Future<void> locationFinish() async {
    /// 创建BMFMarker
    BMFMarker marker = BMFMarker.icon(
        position: BMFCoordinate(
            _locationResult.latitude ?? 0.0, _locationResult.longitude ?? 0.0),
        title: 'flutterMaker',
        identifier: 'flutter_marker',
        icon: 'assets/images/map/icon_mark.png');

    /// 添加Marker
    _myMapController.addMarker(marker);

    ///设置中心点
    _myMapController.setCenterCoordinate(
        BMFCoordinate(
            _locationResult.latitude ?? 0.0, _locationResult.longitude ?? 0.0),
        false);

    // 构造检索参数
    BMFSuggestionSearchOption suggestionSearchOption =
        BMFSuggestionSearchOption(
      keyword: '街道',
      cityname: _locationResult.city,
      location:
          BMFCoordinate(_locationResult.latitude!, _locationResult.longitude!),
      cityLimit: true,
    );
    BMFSuggestionSearch suggestionSearch = BMFSuggestionSearch();
    suggestionSearch.onGetSuggestSearchResult(callback:
        (BMFSuggestionSearchResult result, BMFSearchErrorCode errorCode) {
      print("sug检索回调 result = ${result.toMap()} \n errorCode = ${errorCode}");
      _list = result.suggestionList!;
      if (_list.isEmpty) {
        Toast.show("暂时无法搜索到该位置!");
      }
      isLoading = false;
      setState(() {});
    });
    bool flag = await suggestionSearch.suggestionSearch(suggestionSearchOption);
  }

  /// 设置地图参数
  BaiduLocationAndroidOption initAndroidOptions() {
    BaiduLocationAndroidOption options = BaiduLocationAndroidOption(
        coorType: 'bd09ll',
        locationMode: BMFLocationMode.hightAccuracy,
        isNeedAddress: true,
        isNeedAltitude: true,
        isNeedLocationPoiList: true,
        isNeedNewVersionRgc: true,
        isNeedLocationDescribe: true,
        openGps: true,
        locationPurpose: BMFLocationPurpose.sport,
        coordType: BMFLocationCoordType.bd09ll);
    return options;
  }

  BaiduLocationIOSOption initIOSOptions() {
    BaiduLocationIOSOption options = BaiduLocationIOSOption(
        coordType: BMFLocationCoordType.bd09ll,
        BMKLocationCoordinateType: 'BMKLocationCoordinateTypeBMK09LL',
        desiredAccuracy: BMFDesiredAccuracy.best);
    return options;
  }

  /// 启动定位
  Future<void> _startLocation() async {
    isLoading = true;
    if (Platform.isIOS) {
      await myLocPlugin
          .singleLocation({'isReGeocode': true, 'isNetworkState': true});
    } else if (Platform.isAndroid) {
      await myLocPlugin.startLocation();
    }
  }

  /// 创建完成回调
  void onBMFMapCreated(BMFMapController controller) {
    _myMapController = controller;

    /// 地图加载回调
    _myMapController.setMapDidLoadCallback(callback: () {});
  }

  /// 设置地图参数
  BMFMapOptions initMapOptions() {
    BMFMapOptions mapOptions = BMFMapOptions(
      center: BMFCoordinate(39.917215, 116.380341),
      zoomLevel: 18,
    );
    return mapOptions;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: SearchBar(
        hintText: '搜索地址',
        onPressed: (text) async {
          isLoading = true;
          _controller.animateTo(0.0,
              duration: const Duration(milliseconds: 10), curve: Curves.ease);
          _index = 0;
          // 构造检索参数
          BMFSuggestionSearchOption suggestionSearchOption =
              BMFSuggestionSearchOption(
            keyword: text,
            cityname: _locationResult.city,
            location: BMFCoordinate(
                _locationResult.latitude!, _locationResult.longitude!),
            cityLimit: true,
          );
          BMFSuggestionSearch suggestionSearch = BMFSuggestionSearch();
          suggestionSearch.onGetSuggestSearchResult(callback:
              (BMFSuggestionSearchResult result, BMFSearchErrorCode errorCode) {
            print(
                "sug检索回调 result = ${result.toMap()} \n errorCode = ${errorCode}");
            _list = result.suggestionList!;
            if (_list.isEmpty) {
              Toast.show("暂时无法搜索到该位置!");
            }
            isLoading = false;
            setState(() {});
          });
          bool flag =
              await suggestionSearch.suggestionSearch(suggestionSearchOption);
        },
      ),
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Expanded(
              flex: 9,
              child: BMFMapWidget(
                onBMFMapCreated: (BMFMapController controller) {
                  onBMFMapCreated(controller);
                },
                mapOptions: initMapOptions(),
              ),
            ),
            Expanded(
              flex: 11,
              child: isLoading
                  ? const GFLoader()
                  : ListView.separated(
                      controller: _controller,
                      itemCount: _list.length,
                      separatorBuilder: (_, index) => const Divider(),
                      itemBuilder: (_, index) {
                        return _AddressItem(
                          isSelected: _index == index,
                          poi: _list[index],
                          onTap: () {
                            _index = index;
                            _myMapController.updateMapOptions(BMFMapOptions(
                                center: BMFCoordinate(
                                    _list[index].location!.latitude,
                                    _list[index].location!.longitude)));

                            /// 创建BMFMarker
                            BMFMarker marker = BMFMarker.icon(
                                position: BMFCoordinate(
                                    _list[index].location!.latitude,
                                    _list[index].location!.longitude),
                                title: 'flutterMaker',
                                identifier: 'flutter_marker',
                                icon: 'assets/images/map/icon_mark.png');

                            /// 添加Marker
                            _myMapController.addMarker(marker);

                            ///设置中心点
                            _myMapController.setCenterCoordinate(
                                BMFCoordinate(_list[index].location!.latitude,
                                    _list[index].location!.longitude),
                                false);

                            setState(() {});
                          },
                        );
                      },
                    ),
            ),
            MyButton(
              onPressed: () {
                if (_list.isEmpty) {
                  Toast.show('未选择地址!');
                  return;
                }
                NavigatorUtils.goBackWithParams(context, _list[_index]);
              },
              text: '确认选择地址',
            )
          ],
        ),
      ),
    );
  }
}

class _AddressItem extends StatelessWidget {
  const _AddressItem({
    Key? key,
    required this.poi,
    this.isSelected = false,
    this.onTap,
  }) : super(key: key);

  final BMFSuggestionInfo poi;
  final bool isSelected;
  final GestureTapCallback? onTap;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: onTap,
      child: Container(
        alignment: Alignment.centerLeft,
        padding: const EdgeInsets.symmetric(horizontal: 16.0),
        height: 50.0,
        child: Row(
          children: <Widget>[
            Expanded(
              child: Text(
                '${poi.city} ${poi.district} ${poi.address}',
              ),
            ),
            Visibility(
              visible: isSelected,
              child: const Icon(Icons.done, color: Colors.blue),
            )
          ],
        ),
      ),
    );
  }
}