map_choicePoint.dart 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. import 'package:amap_map_fluttify/amap_map_fluttify.dart';
  2. import 'package:amap_search_fluttify/amap_search_fluttify.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/services.dart';
  5. import 'package:liftmanager/utils/fast_notification.dart';
  6. import 'package:liftmanager/utils/location_helper.dart';
  7. import 'package:liftmanager/utils/toast.dart';
  8. import 'package:liftmanager/widgets/app_bar.dart';
  9. import 'package:permission_handler/permission_handler.dart';
  10. import '../../../main.dart';
  11. import '../../../utils/toast.dart';
  12. /**
  13. * 地图选择点控件
  14. */
  15. class MyHomePage extends StatefulWidget {
  16. /**
  17. * 选择点后回调事件
  18. */
  19. // final Function onChoicePoint;
  20. // MyHomePage(this.onChoicePoint);
  21. MyHomePage(this.type);
  22. final String type;
  23. @override
  24. _MapChoicePointState createState() => _MapChoicePointState();
  25. }
  26. class _MapChoicePointState extends State<MyHomePage>
  27. with SingleTickerProviderStateMixin {
  28. //----属性----
  29. //地图控制器
  30. AmapController _amapController;
  31. //选择的点
  32. Marker _markerSelect;
  33. //搜索出来之后选择的点
  34. Marker _markerSeached;
  35. //所在城市
  36. String city;
  37. //搜索框文字控制器
  38. TextEditingController _serachController;
  39. //自定义marker点图标图片路径
  40. Uri _imgUri = Uri.parse('images/icon_star_selected.png');
  41. //----方法----
  42. /**
  43. * 获取权限
  44. */
  45. Future<bool> _requestPermission() async {
  46. final permissions = await PermissionHandler()
  47. .requestPermissions([PermissionGroup.location]);
  48. if (permissions[PermissionGroup.location] == PermissionStatus.granted) {
  49. return true;
  50. } else {
  51. // toasts('需要定位权限!');
  52. return false;
  53. }
  54. }
  55. setlatlng() {
  56. var helper = LocationHelper();
  57. helper
  58. .getLocation((String lat, String lng, String cityName, {provinceName}) {
  59. if (lat != null && lng != null) {
  60. helper.stopGettingLocation();
  61. }
  62. var latLng = LatLng(double.parse(lat), double.parse(lng));
  63. _amapController?.setCenterCoordinate(latLng);
  64. // setState(() {});
  65. // NavigatorUtils.goBackWithParams(context, "$lng,$lat");
  66. });
  67. }
  68. /**
  69. * 根据搜索条件选出想要的点
  70. */
  71. Future _openModalBottomSheet() async {
  72. //收起键盘
  73. print("----------");
  74. FocusScope.of(context).requestFocus(FocusNode());
  75. //根据关键字及城市进行搜索
  76. final poiList = await AmapSearch.searchKeyword(
  77. _serachController.text,
  78. city: city,
  79. );
  80. List<Map> points = [];
  81. //便利拼接信息
  82. for (var item in poiList) {
  83. points.add({
  84. 'title': item.title,
  85. 'address': item.adName + item.address,
  86. 'position': item.latLng,
  87. });
  88. }
  89. //弹出底部对话框并等待选择
  90. final option = await showModalBottomSheet(
  91. context: context,
  92. builder: (BuildContext context) {
  93. return points.length > 0
  94. ? ListView.builder(
  95. itemCount: points.length,
  96. itemBuilder: (BuildContext itemContext, int i) {
  97. return ListTile(
  98. title: Text(points[i]['title']),
  99. subtitle: Text(points[i]['address']),
  100. onTap: () {
  101. Navigator.pop(context, points[i]);
  102. print(points[i]);
  103. print(4444444);
  104. toCenter(points[i]);
  105. },
  106. );
  107. },
  108. )
  109. : Container(
  110. alignment: Alignment.center,
  111. padding: EdgeInsets.all(40),
  112. child: Text('暂无数据'),
  113. );
  114. },
  115. );
  116. if (option != null) {
  117. LatLng selectlatlng = option['position'];
  118. //将地图中心点移动到选择的点
  119. _amapController.setCenterCoordinate(
  120. LatLng(selectlatlng.latitude, selectlatlng.longitude));
  121. //删除原来地图上搜索出来的点
  122. if (_markerSeached != null) {
  123. _markerSeached.remove();
  124. }
  125. //将搜索出来的点显示在界面上 --此处不能使用自定义图标的marker,使用会报错,至今也没有解决
  126. _markerSeached = await _amapController.addMarker(MarkerOption(
  127. latLng: selectlatlng,
  128. ));
  129. ReGeocode reGeocodeList = await AmapSearch.searchReGeocode(
  130. selectlatlng,
  131. );
  132. // print(await reGeocodeList.toFutureString());
  133. // print(await reGeocodeList.provinceName);
  134. // print(await reGeocodeList.cityName);
  135. // print(await reGeocodeList.districtName);
  136. print("reGeocodeList.provinceName=================");
  137. var addressM = (await reGeocodeList.provinceName) +
  138. (await reGeocodeList.cityName) +
  139. (await reGeocodeList.districtName);
  140. var address = await reGeocodeList.formatAddress;
  141. showAlert(
  142. navigatorKey.currentState.overlay.context,
  143. "提示",
  144. "出诊地址为: $address",
  145. "确定",
  146. () {
  147. Navigator.of(navigatorKey.currentState.overlay.context)..pop();
  148. if (context != null) {
  149. Navigator.of(navigatorKey.currentState.overlay.context)..pop();
  150. }
  151. // setExtAddress(address+","+coord.latitude.toString()+","+coord.longitude.toString());
  152. String setAddress = address +
  153. "," +
  154. selectlatlng.latitude.toString() +
  155. "," +
  156. selectlatlng.longitude.toString();
  157. String setAddressMaster = addressM;
  158. if (widget.type == "1") {
  159. FastNotification.push("set_address", setAddress);
  160. } else if (widget.type == "2") {
  161. FastNotification.push("set_address_master", setAddressMaster);
  162. }
  163. },
  164. txt2: "取消",
  165. onPre2: () {
  166. Navigator.of(navigatorKey.currentState.overlay.context)..pop();
  167. },
  168. );
  169. }
  170. }
  171. Future toCenter(option) async {
  172. print(option['position']);
  173. print("======================");
  174. LatLng selectlatlng = option['position'];
  175. //将地图中心点移动到选择的点
  176. _amapController.setCenterCoordinate(
  177. LatLng(selectlatlng.latitude, selectlatlng.longitude));
  178. //删除原来地图上搜索出来的点
  179. if (_markerSeached != null) {
  180. _markerSeached.remove();
  181. }
  182. //将搜索出来的点显示在界面上 --此处不能使用自定义图标的marker,使用会报错,至今也没有解决
  183. _markerSeached = await _amapController.addMarker(MarkerOption(
  184. latLng: selectlatlng,
  185. ));
  186. }
  187. @override
  188. void initState() {
  189. super.initState();
  190. _serachController = TextEditingController();
  191. _requestPermission();
  192. }
  193. @override
  194. void dispose() {
  195. super.dispose();
  196. }
  197. @override
  198. Widget build(BuildContext context) {
  199. return Scaffold(
  200. appBar: MyAppBar(
  201. centerTitle: "地图选择",
  202. ),
  203. body: Stack(
  204. alignment: AlignmentDirectional.topCenter,
  205. children: <Widget>[
  206. AmapView(
  207. // 地图类型 (可选)
  208. mapType: MapType.Standard,
  209. // 是否显示缩放控件 (可选)
  210. // showZoomControl: true,
  211. // 是否显示指南针控件 (可选)
  212. showCompass: true,
  213. // 是否显示比例尺控件 (可选)
  214. showScaleControl: true,
  215. // 是否使能缩放手势 (可选)
  216. zoomGesturesEnabled: true,
  217. // 是否使能滚动手势 (可选)
  218. scrollGesturesEnabled: true,
  219. // 是否使能旋转手势 (可选)
  220. rotateGestureEnabled: false,
  221. // 是否使能倾斜手势 (可选)
  222. tiltGestureEnabled: false,
  223. // 缩放级别 (可选)
  224. zoomLevel: 16,
  225. // 中心点坐标 (可选)
  226. // centerCoordinate: LatLng(39, 116),
  227. // 标记 (可选)
  228. markers: <MarkerOption>[],
  229. // 标识点击回调 (可选)
  230. onMarkerClicked: (Marker marker) async {
  231. if (_markerSeached == null) {
  232. return;
  233. }
  234. //获取点击点的位置
  235. var location = await marker.location;
  236. var lon = location.longitude;
  237. var lat = location.latitude;
  238. //获取搜索点的位置
  239. var slocation = await _markerSeached.location;
  240. var slon = slocation.longitude;
  241. var slat = slocation.latitude;
  242. //比较位置
  243. if (lon == slon && lat == slat) {
  244. //移除原来的点
  245. if (_markerSeached != null) {
  246. _markerSeached.remove();
  247. }
  248. if (_markerSelect != null) {
  249. _markerSelect.remove();
  250. }
  251. //画上新的点
  252. _markerSelect = await _amapController.addMarker(
  253. MarkerOption(
  254. latLng: location,
  255. // iconUri: _imgUri,
  256. // imageConfig: createLocalImageConfiguration(context),
  257. width: 64,
  258. height: 64,
  259. anchorV: 0.7,
  260. anchorU: 0.5,
  261. ),
  262. );
  263. }
  264. },
  265. // 地图点击回调 (可选)
  266. onMapClicked: (LatLng coord) async {
  267. print("//////////////");
  268. print(coord.latitude);
  269. print(coord.longitude);
  270. String address;
  271. String addressM;
  272. /// 逆地理编码(坐标转地址)
  273. ReGeocode reGeocodeList = await AmapSearch.searchReGeocode(
  274. coord,
  275. );
  276. // print(await reGeocodeList.toFutureString());
  277. // print(await reGeocodeList.provinceName);
  278. // print(await reGeocodeList.cityName);
  279. // print(await reGeocodeList.districtName);
  280. print("reGeocodeList.provinceName=================");
  281. addressM = (await reGeocodeList.provinceName) +
  282. (await reGeocodeList.cityName) +
  283. (await reGeocodeList.districtName);
  284. address = await reGeocodeList.formatAddress;
  285. print(address);
  286. print(address +
  287. "," +
  288. coord.latitude.toString() +
  289. "," +
  290. coord.longitude.toString());
  291. if (_amapController != null) {
  292. //移除原来的点
  293. if (_markerSelect != null) {
  294. _markerSelect.remove();
  295. }
  296. if (_markerSeached != null) {
  297. _markerSeached.remove();
  298. }
  299. _markerSeached = await _amapController.addMarker(MarkerOption(
  300. latLng: coord,
  301. ));
  302. //画上新的点
  303. // _markerSelect = await _amapController.addMarker(MarkerOption(
  304. // latLng: coord,
  305. // iconUri: _imgUri,
  306. // imageConfig: createLocalImageConfiguration(context),
  307. // width: 64,
  308. // height: 64,
  309. // anchorV: 0.7,
  310. // anchorU: 0.5));
  311. // widget.onChoicePoint(coord);
  312. showAlert(
  313. navigatorKey.currentState.overlay.context,
  314. "提示",
  315. "出诊地址为: $address",
  316. "确定",
  317. () {
  318. Navigator.of(navigatorKey.currentState.overlay.context)
  319. ..pop();
  320. if (context != null) {
  321. Navigator.of(navigatorKey.currentState.overlay.context)
  322. ..pop();
  323. }
  324. // setExtAddress(address+","+coord.latitude.toString()+","+coord.longitude.toString());
  325. String setAddress = address +
  326. "," +
  327. coord.latitude.toString() +
  328. "," +
  329. coord.longitude.toString();
  330. String setAddressMaster = addressM;
  331. if (widget.type == "1") {
  332. FastNotification.push("set_address", setAddress);
  333. } else if (widget.type == "2") {
  334. FastNotification.push(
  335. "set_address_master", setAddressMaster);
  336. }
  337. },
  338. txt2: "取消",
  339. onPre2: () {
  340. Navigator.of(navigatorKey.currentState.overlay.context)
  341. ..pop();
  342. },
  343. );
  344. }
  345. },
  346. onMapMoveStart: (MapMove move) {},
  347. // 地图创建完成回调 (可选)
  348. onMapCreated: (controller) async {
  349. _amapController = controller;
  350. //申请权限
  351. if (await _requestPermission()) {
  352. //获取所在城市
  353. print(123456789);
  354. // final location = await AmapLocation.fetchLocation();
  355. // city = await location.city;
  356. // print(location);
  357. // print(city);
  358. setlatlng();
  359. print(1111111);
  360. //显示自己的定位
  361. await controller.showMyLocation(MyLocationOption());
  362. // await initSerach();
  363. }
  364. },
  365. ),
  366. Container(
  367. margin: EdgeInsets.all(20),
  368. width: MediaQuery.of(context).size.width,
  369. height: 46,
  370. decoration: BoxDecoration(color: Colors.white),
  371. child: Row(
  372. mainAxisAlignment: MainAxisAlignment.spaceAround,
  373. children: <Widget>[
  374. Container(
  375. padding: EdgeInsets.all(8),
  376. width: MediaQuery.of(context).size.width - 20 - 80,
  377. child: TextField(
  378. controller: _serachController,
  379. decoration: InputDecoration(border: InputBorder.none),
  380. inputFormatters: <TextInputFormatter>[
  381. LengthLimitingTextInputFormatter(10) //限制长度
  382. ],
  383. ),
  384. ),
  385. IconButton(
  386. icon: Icon(Icons.search),
  387. onPressed: _openModalBottomSheet)
  388. ],
  389. ),
  390. )
  391. ],
  392. ));
  393. }
  394. // void setExtAddress (String str)async{
  395. // SharedPreferences prefs = await SharedPreferences.getInstance();
  396. // prefs.setString("extAddress",str);
  397. // }
  398. }