map_choicePoint.dart 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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/routers/fluro_navigator.dart';
  6. import 'package:liftmanager/utils/fast_notification.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. /**
  56. * 根据搜索条件选出想要的点
  57. */
  58. Future _openModalBottomSheet() async {
  59. //收起键盘
  60. print("----------");
  61. FocusScope.of(context).requestFocus(FocusNode());
  62. //根据关键字及城市进行搜索
  63. final poiList = await AmapSearch.searchKeyword(
  64. _serachController.text,
  65. city: city,
  66. );
  67. List<Map> points = [];
  68. //便利拼接信息
  69. for (var item in poiList) {
  70. points.add({
  71. 'title': item.title,
  72. 'address': item.adName + item.address,
  73. 'position': item.latLng,
  74. });
  75. }
  76. //弹出底部对话框并等待选择
  77. final option = await showModalBottomSheet(
  78. context: context,
  79. builder: (BuildContext context) {
  80. return points.length > 0
  81. ? ListView.builder(
  82. itemCount: points.length,
  83. itemBuilder: (BuildContext itemContext, int i) {
  84. return ListTile(
  85. title: Text(points[i]['title']),
  86. subtitle: Text(points[i]['address']),
  87. onTap: () {
  88. Navigator.pop(context, points[i]);
  89. print(points[i]);
  90. print(4444444);
  91. toCenter(points[i]);
  92. },
  93. );
  94. },
  95. )
  96. : Container(
  97. alignment: Alignment.center,
  98. padding: EdgeInsets.all(40),
  99. child: Text('暂无数据'),
  100. );
  101. },
  102. );
  103. if (option != null) {
  104. LatLng selectlatlng = option['position'];
  105. //将地图中心点移动到选择的点
  106. _amapController.setCenterCoordinate(
  107. LatLng(selectlatlng.latitude, selectlatlng.longitude));
  108. //删除原来地图上搜索出来的点
  109. if (_markerSeached != null) {
  110. _markerSeached.remove();
  111. }
  112. //将搜索出来的点显示在界面上 --此处不能使用自定义图标的marker,使用会报错,至今也没有解决
  113. _markerSeached = await _amapController.addMarker(MarkerOption(
  114. latLng: selectlatlng,
  115. ));
  116. }
  117. }
  118. Future toCenter(option) async {
  119. print(option['position']);
  120. print("======================");
  121. LatLng selectlatlng = option['position'];
  122. //将地图中心点移动到选择的点
  123. _amapController.setCenterCoordinate(
  124. LatLng(selectlatlng.latitude, selectlatlng.longitude));
  125. //删除原来地图上搜索出来的点
  126. if (_markerSeached != null) {
  127. _markerSeached.remove();
  128. }
  129. //将搜索出来的点显示在界面上 --此处不能使用自定义图标的marker,使用会报错,至今也没有解决
  130. _markerSeached = await _amapController.addMarker(MarkerOption(
  131. latLng: selectlatlng,
  132. ));
  133. }
  134. @override
  135. void initState() {
  136. super.initState();
  137. _serachController = TextEditingController();
  138. _requestPermission();
  139. }
  140. @override
  141. void dispose() {
  142. super.dispose();
  143. }
  144. @override
  145. Widget build(BuildContext context) {
  146. return Scaffold(
  147. appBar: MyAppBar(
  148. centerTitle: "地图选择",
  149. ),
  150. body: Stack(
  151. alignment: AlignmentDirectional.topCenter,
  152. children: <Widget>[
  153. AmapView(
  154. // 地图类型 (可选)
  155. mapType: MapType.Standard,
  156. // 是否显示缩放控件 (可选)
  157. // showZoomControl: true,
  158. // 是否显示指南针控件 (可选)
  159. showCompass: true,
  160. // 是否显示比例尺控件 (可选)
  161. showScaleControl: true,
  162. // 是否使能缩放手势 (可选)
  163. zoomGesturesEnabled: true,
  164. // 是否使能滚动手势 (可选)
  165. scrollGesturesEnabled: true,
  166. // 是否使能旋转手势 (可选)
  167. rotateGestureEnabled: false,
  168. // 是否使能倾斜手势 (可选)
  169. tiltGestureEnabled: false,
  170. // 缩放级别 (可选)
  171. zoomLevel: 16,
  172. // 中心点坐标 (可选)
  173. // centerCoordinate: LatLng(39, 116),
  174. // 标记 (可选)
  175. markers: <MarkerOption>[],
  176. // 标识点击回调 (可选)
  177. onMarkerClicked: (Marker marker) async {
  178. if (_markerSeached == null) {
  179. return;
  180. }
  181. //获取点击点的位置
  182. var location = await marker.location;
  183. var lon = location.longitude;
  184. var lat = location.latitude;
  185. //获取搜索点的位置
  186. var slocation = await _markerSeached.location;
  187. var slon = slocation.longitude;
  188. var slat = slocation.latitude;
  189. //比较位置
  190. if (lon == slon && lat == slat) {
  191. //移除原来的点
  192. if (_markerSeached != null) {
  193. _markerSeached.remove();
  194. }
  195. if (_markerSelect != null) {
  196. _markerSelect.remove();
  197. }
  198. //画上新的点
  199. _markerSelect = await _amapController.addMarker(
  200. MarkerOption(
  201. latLng: location,
  202. // iconUri: _imgUri,
  203. // imageConfig: createLocalImageConfiguration(context),
  204. width: 64,
  205. height: 64,
  206. anchorV: 0.7,
  207. anchorU: 0.5,
  208. ),
  209. );
  210. }
  211. },
  212. // 地图点击回调 (可选)
  213. onMapClicked: (LatLng coord) async {
  214. print("//////////////");
  215. print(coord.latitude);
  216. print(coord.longitude);
  217. String address;
  218. String addressM;
  219. /// 逆地理编码(坐标转地址)
  220. ReGeocode reGeocodeList = await AmapSearch.searchReGeocode(
  221. coord,
  222. );
  223. // print(await reGeocodeList.toFutureString());
  224. // print(await reGeocodeList.provinceName);
  225. // print(await reGeocodeList.cityName);
  226. // print(await reGeocodeList.districtName);
  227. print("reGeocodeList.provinceName=================");
  228. addressM = (await reGeocodeList.provinceName) +
  229. (await reGeocodeList.cityName) +
  230. (await reGeocodeList.districtName);
  231. address = await reGeocodeList.formatAddress;
  232. print(address);
  233. print(address +
  234. "," +
  235. coord.latitude.toString() +
  236. "," +
  237. coord.longitude.toString());
  238. if (_amapController != null) {
  239. //移除原来的点
  240. if (_markerSelect != null) {
  241. _markerSelect.remove();
  242. }
  243. if (_markerSeached != null) {
  244. _markerSeached.remove();
  245. }
  246. //画上新的点
  247. _markerSelect = await _amapController.addMarker(MarkerOption(
  248. latLng: coord,
  249. // iconUri: _imgUri,
  250. // imageConfig: createLocalImageConfiguration(context),
  251. width: 64,
  252. height: 64,
  253. anchorV: 0.7,
  254. anchorU: 0.5));
  255. // widget.onChoicePoint(coord);
  256. showAlert(
  257. navigatorKey.currentState.overlay.context,
  258. "提示",
  259. "出诊地址为: $address",
  260. "确定",
  261. () {
  262. Navigator.of(navigatorKey.currentState.overlay.context)
  263. ..pop();
  264. if (context != null) {
  265. Navigator.of(navigatorKey.currentState.overlay.context)
  266. ..pop();
  267. }
  268. // setExtAddress(address+","+coord.latitude.toString()+","+coord.longitude.toString());
  269. String setAddress = address +
  270. "," +
  271. coord.latitude.toString() +
  272. "," +
  273. coord.longitude.toString();
  274. String setAddressMaster = addressM;
  275. if (widget.type == "1") {
  276. FastNotification.push("set_address", setAddress);
  277. } else if (widget.type == "2") {
  278. FastNotification.push(
  279. "set_address_master", setAddressMaster);
  280. }
  281. },
  282. txt2: "取消",
  283. onPre2: () {
  284. Navigator.of(navigatorKey.currentState.overlay.context)
  285. ..pop();
  286. },
  287. );
  288. }
  289. },
  290. onMapMoveStart: (MapMove move) {},
  291. // 地图创建完成回调 (可选)
  292. onMapCreated: (controller) async {
  293. _amapController = controller;
  294. //申请权限
  295. if (await _requestPermission()) {
  296. //获取所在城市
  297. print(123456789);
  298. // final location = await AmapLocation.fetchLocation();
  299. // city = await location.city;
  300. // print(location);
  301. // print(city);
  302. print(1111111);
  303. //显示自己的定位
  304. await controller.showMyLocation(MyLocationOption());
  305. // await initSerach();
  306. }
  307. },
  308. ),
  309. Container(
  310. margin: EdgeInsets.all(20),
  311. width: MediaQuery.of(context).size.width,
  312. height: 46,
  313. decoration: BoxDecoration(color: Colors.white),
  314. child: Row(
  315. mainAxisAlignment: MainAxisAlignment.spaceAround,
  316. children: <Widget>[
  317. Container(
  318. padding: EdgeInsets.all(8),
  319. width: MediaQuery.of(context).size.width - 20 - 80,
  320. child: TextField(
  321. controller: _serachController,
  322. decoration: InputDecoration(border: InputBorder.none),
  323. inputFormatters: <TextInputFormatter>[
  324. LengthLimitingTextInputFormatter(10) //限制长度
  325. ],
  326. ),
  327. ),
  328. IconButton(
  329. icon: Icon(Icons.search),
  330. onPressed: _openModalBottomSheet)
  331. ],
  332. ),
  333. )
  334. ],
  335. ));
  336. }
  337. // void setExtAddress (String str)async{
  338. // SharedPreferences prefs = await SharedPreferences.getInstance();
  339. // prefs.setString("extAddress",str);
  340. // }
  341. }