From 70a344485bd0c9b68ac91f72ed23ec5bfa998b09 Mon Sep 17 00:00:00 2001 From: admin <weikou2014> Date: 星期四, 25 十一月 2021 19:30:25 +0800 Subject: [PATCH] 功能完善 --- lib/ui/main/location.dart | 787 ++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 560 insertions(+), 227 deletions(-) diff --git a/lib/ui/main/location.dart b/lib/ui/main/location.dart index 136b426..b5cd841 100644 --- a/lib/ui/main/location.dart +++ b/lib/ui/main/location.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:io'; -import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter/cupertino.dart'; @@ -8,46 +7,31 @@ import 'package:flutter/rendering.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:locations/api/http.dart'; +import 'package:locations/model/map/location_model.dart'; +import 'package:locations/model/map/location_user_model.dart'; +import 'package:locations/model/user/user_info.dart'; import 'package:locations/ui/map/location_search.dart'; -import 'package:locations/ui/mine/advice.dart'; -import 'package:locations/ui/mine/permission.dart'; -import 'package:locations/ui/mine/settings.dart'; -import 'package:locations/ui/mine/share_to_friends.dart'; -import 'package:locations/ui/mine/try_functions.dart'; +import 'package:locations/ui/mine/add_location_person.dart'; +import 'package:locations/ui/mine/login.dart'; import 'package:locations/ui/widget/button.dart'; +import 'package:locations/ui/widget/capture.dart'; +import 'package:locations/ui/widget/dialog.dart'; +import 'package:locations/ui/widget/map_marker.dart'; +import 'package:locations/utils/event_bus_util.dart'; +import 'package:locations/utils/global.dart'; import 'package:locations/utils/location_util.dart'; import 'package:locations/utils/map_util.dart'; import 'package:locations/utils/pageutils.dart'; +import 'package:locations/utils/string_util.dart'; import 'package:locations/utils/ui_constant.dart'; +import 'package:locations/utils/ui_utils.dart'; +import 'package:locations/utils/user_util.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:permission_handler/permission_handler.dart'; typedef OnPositionHiidenChange = void Function(bool hidden); BMFMapController? _mapController; - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primaryColor: Color.fromARGB(255, 150, 150, 150)), - home: LocationPage(title: ''), - ); - } -} class LocationPage extends StatefulWidget { LocationPage({Key? key, required this.title}) : super(key: key); @@ -70,18 +54,84 @@ class _LocationPageState extends State<LocationPage> with AutomaticKeepAliveClientMixin { GlobalKey rootWidgetKey = GlobalKey(); + CaptureController _captureController = CaptureController(); + + //鐢ㄦ埛marker + BMFMarker? userMarker; + String? portrait; + BaiduLocation? location; BMFMapOptions mapOptions = BMFMapOptions( showMapScaleBar: false, mapType: BMFMapType.Standard, - center: BMFCoordinate(39.917215, 116.380341), + center: Global.currentPosition != null + ? Global.currentPosition + : BMFCoordinate(39.917215, 116.380341), mapScaleBarPosition: BMFPoint(0, 200), zoomLevel: 12, mapPadding: BMFEdgeInsets(left: 30, top: 0, right: 30, bottom: 200)); + var eventBusLocation; + @override void initState() { super.initState(); + eventBusLocation = eventBus.on<UserLocationInfoEventBus>().listen((event) { + //璁剧疆鐢ㄦ埛澶村儚 + setState(() { + portrait = (event.user == null || + StringUtil.isNullOrEmpty(event.user!.portrait) + ? null + : event.user!.portrait); + }); + location = event.location; + drawMarker( + BMFCoordinate(event.location!.latitude!, event.location!.longitude!)); + }); + _getLocationInvite(); + } + + void _getLocationInvite() async { + var uid = await UserUtil.getUid(); + if (uid == null) { + return; + } + Map<String, dynamic>? result = + await LocationApiUtil.getInviteLocation(uid!); + if (result!["code"] == 0) { + LocationUserModel model = LocationUserModel.fromJson(result["data"]); + showGeneralDialog( + context: context, + pageBuilder: (BuildContext buildContext, Animation<double> animation, + Animation<double> secondaryAnimation) { + return RequireLocationDialog(model.targetPhone!, () { + LocationApiUtil.rejectInviteLocation(uid, model.id!) + .then((value) { + if (value!["code"] == 0) { + Navigator.of(context).pop(); + } else { + ToastUtil.toast(value!["msg"]); + } + }); + }, () { + LocationApiUtil.agreeInviteLocation(uid, model.id!).then((value) { + if (value!["code"] == 0) { + Navigator.of(context).pop(); + } else { + ToastUtil.toast(value!["msg"]); + } + }); + }); + }); + } + } + + + + @override + void dispose() { + super.dispose(); + (eventBusLocation as StreamSubscription).cancel(); } @override @@ -95,17 +145,28 @@ PositionInfoPage(), Positioned( top: -100, - child: - RepaintBoundary( - key: rootWidgetKey, - child: Image.asset( - "assets/images/mine/icon_mine_default_portrait.png", - height: 33, - width: 33, - ))), + child: RepaintBoundary( + key: rootWidgetKey, + child: Image.asset( + "assets/images/mine/icon_mine_default_portrait.png", + height: 33, + width: 33, + ))), Align( alignment: Alignment.bottomCenter, child: getAddLocationObjectView()), + + //鍦板浘marker鎴浘缁勪欢 + Positioned( + top: -100, + child: CaptureWidget( + widget: PersonLocationMarker(portrait == null + ? Image.asset( + "assets/images/mine/icon_mine_default_portrait.png", + ) + : Image.network(portrait!)), + captureController: _captureController, + )) ], )); } @@ -127,82 +188,79 @@ child: BMFMapWidget( onBMFMapCreated: (controller) { _mapController = controller; - - - Timer(Duration(seconds: 3),(){ - _capturePng().then((value) { - BMFMarker marker = BMFMarker( - position: BMFCoordinate(39.928617, 116.40329), - title: 'flutterMaker', - identifier: 'flutter_marker', - icon:value!.path); - - /// 娣诲姞Marker - _mapController?.addMarker(marker); - }); - }); - - - + if (location != null) { + drawMarker( + BMFCoordinate(location!.latitude!, location!.longitude!)); + } }, mapOptions: mapOptions, ), ); } - Future<File?> _capturePng() async { - await Permission.storage.request(); - try { - RenderRepaintBoundary? boundary = rootWidgetKey.currentContext! - .findRenderObject() as RenderRepaintBoundary; - var image = await boundary.toImage(pixelRatio: 3.0); - ByteData? byteData = await image.toByteData(format: ImageByteFormat.png); - Uint8List pngBytes = byteData!.buffer.asUint8List(); - Directory? tempDir = await getExternalStorageDirectory(); - String tempPath = tempDir!.path; - String shareImgPath = "$tempPath/test.jpg"; - File(shareImgPath!).writeAsBytesSync(pngBytes!); - int length=await File(shareImgPath!).length(); - print("鎴浘澶у皬涓猴細${length}"); - return File(shareImgPath!); - } catch (e) { - print(e); + //鐢籱arker + void drawMarker(BMFCoordinate location) async { + if (_mapController == null) { + return; } - return null; + Directory? tempDir = await getExternalStorageDirectory(); + String tempPath = tempDir!.path; + File? file = + await _captureController.capturePng("$tempPath/location_person.png"); + if (userMarker == null) { + userMarker = + await MapUtil.addMarker(_mapController, location, file!.path); + } else { + userMarker!.updateIcon(file!.path); + userMarker!.updatePosition(location); + } + _mapController!.setCenterCoordinate(location, true); } //娣诲姞鎯冲畾浣嶇殑浜� Widget getAddLocationObjectView() { - return Container( - alignment: Alignment.topCenter, - height: 72, - margin: const EdgeInsets.fromLTRB(10, 0, 10, 0), - padding: const EdgeInsets.fromLTRB(0, 18, 0, 0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(10), topRight: Radius.circular(10)), - boxShadow: getViewShadow()), - child: Flex( - direction: Axis.horizontal, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Image.asset( - "assets/images/common/icon_person.png", - height: 17, + return InkWell( + onTap: () { + UserUtil.isLogin().then((value) { + if (!value) { + NavigatorUtil.navigateToNextPage( + context, LoginPage(title: ""), (data) {}); + return; + } + NavigatorUtil.navigateToNextPage( + context, AddLocationPersonPage(title: ""), (data) {}); + }); + }, + child: Container( + alignment: Alignment.topCenter, + height: 72, + margin: const EdgeInsets.fromLTRB(10, 0, 10, 0), + padding: const EdgeInsets.fromLTRB(0, 18, 0, 0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), topRight: Radius.circular(10)), + boxShadow: getViewShadow()), + child: Flex( + direction: Axis.horizontal, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset( + "assets/images/common/icon_person.png", + height: 17, + ), + Container( + width: 11, + height: 1, + ), + const Text( + "娣诲姞鎯冲畾浣嶇殑瀵硅薄", + style: TextStyle(color: ColorConstant.theme, fontSize: 15), + ) + ], ), - Container( - width: 11, - height: 1, - ), - const Text( - "娣诲姞鎯冲畾浣嶇殑瀵硅薄", - style: TextStyle(color: ColorConstant.theme, fontSize: 15), - ) - ], - ), - ); + )); } @override @@ -234,7 +292,101 @@ //浣嶇疆淇℃伅鏄惁闅愯棌 bool locationInfoHidden = true; + UserInfo? user; + + BaiduLocation? _location; + GlobalKey rootWidgetKey = GlobalKey(); + + var eventBusLogin; + + List<LocationUserModel>? userList; + + @override + void initState() { + super.initState(); + UserUtil.getUserInfo().then((value) { + setState(() { + user = value; + }); + //寮�濮嬪畾浣� + LocationUtil.startLocation(0, (state, map) { + if (state == LocationState.success) { + BaiduLocation location = BaiduLocation.fromJson(map); + setState(() { + _location = location; + }); + eventBus.fire(UserLocationInfoEventBus(_location, user)); + } + }); + }); + //娉ㄥ唽eventbus + eventBusLogin = eventBus.on<LoginEventBus>().listen((event) { + if (event.isLogin) { + UserUtil.getUserInfo().then((value) { + setState(() { + user = value; + }); + }); + } else { + setState(() { + user = null; + }); + } + }); + } + + @override + void dispose() { + super.dispose(); + //鍙栨秷璁㈤槄 + eventBusLogin.cancel(); + } + + + + void _selectLocationUser() async { + await _getLocationUsers(); + + if (userList == null || userList!.isEmpty) { + ToastUtil.toast("璇峰厛娣诲姞瀹氫綅瀵硅薄"); + return; + } + + var selectUserType = await showGeneralDialog( + context: context, + pageBuilder: (BuildContext buildContext, Animation<double> animation, + Animation<double> secondaryAnimation) => + ListViewDialog( + ListView.builder( + padding: EdgeInsets.zero, + itemCount: userList!.length, + itemBuilder: (BuildContext context, int index) { + return _getUserItem(userList![index], index); + }), + () { + Navigator.of(context).pop(); + }, + )); + } + + Future _getLocationUsers() async { + var uid = await UserUtil.getUid(); + if (uid == null) return; + Map<String, dynamic>? result = + await LocationApiUtil.getLocationUsers(uid, 1); + + if (result!["code"] == 0) { + List<dynamic> list = result!["data"]["list"]; + List<LocationUserModel> users = []; + list.forEach((element) { + users.add(LocationUserModel.fromJson(element)); + }); + userList = users; + } else { + ToastUtil.toast(result!["msg"]); + } + } @override Widget build(BuildContext context) { @@ -248,8 +400,8 @@ Expanded( child: InkWell( onTap: () { - NavigatorUtil.navigateToNextPage(context, LocationSearchPage(), - (data) { }); + NavigatorUtil.navigateToNextPage( + context, LocationSearchPage(), (data) {}); }, child: Container( alignment: Alignment.center, @@ -303,7 +455,9 @@ child: Stack( children: [ //浣嶇疆淇℃伅 - getPositionInfoView(context), + _location == null + ? Container() + : getPositionInfoView(context), //涓汉淇℃伅 Container( height: 100, @@ -322,31 +476,45 @@ child: Stack( alignment: Alignment.topCenter, children: [ - Flex( - mainAxisAlignment: MainAxisAlignment.center, - direction: Axis.horizontal, - children: [ - Image.asset( - "assets/images/main/icon_location_change_person.png", - width: 13, - ), - Text( - " 鍒囨崲瀹炴椂瀹氫綅浜�", - style: TextStyle( - color: ColorConstant.theme, fontSize: 15), - ) - ], - ), + user == null + ? Container() + : InkWell( + onTap: () { + _selectLocationUser(); + }, + child: Flex( + mainAxisAlignment: MainAxisAlignment.center, + direction: Axis.horizontal, + children: [ + Image.asset( + "assets/images/main/icon_location_change_person.png", + width: 13, + ), + Text( + " 鍒囨崲瀹炴椂瀹氫綅浜�", + style: TextStyle( + color: ColorConstant.theme, + fontSize: 15), + ) + ], + )), //涓汉淇℃伅 Flex( direction: Axis.horizontal, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Image.asset( - "assets/images/mine/icon_mine_default_portrait.png", - height: 33, - width: 33, - ), + user == null + ? Image( + image: AssetImage( + "assets/images/mine/icon_mine_default_portrait.png"), + height: 33, + width: 33, + ) + : Image.network( + user!.portrait!, + width: 33, + height: 33, + ), Container( width: 5, ), @@ -355,23 +523,46 @@ direction: Axis.vertical, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "鎴戣嚜宸�", - softWrap: false, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Color(0xFFA0A0A0), fontSize: 18), - ), - Container( - height: 2, - ), - Text( - "ID:128312", - style: TextStyle( - color: Color(0xFFA0A0A0), fontSize: 12), - ) - ], + children: user == null + ? [ + Container( + width: 60, + child: MyOutlineButton( + "鍘荤櫥褰�", + 5, + onClick: () { + NavigatorUtil.navigateToNextPage( + context, LoginPage(title: ""), + (data) { + UserUtil.getUserInfo() + .then((value) { + setState(() { + user = value; + }); + }); + }); + }, + )) + ] + : [ + Text( + user!.nickName!, + softWrap: false, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Color(0xFFA0A0A0), + fontSize: 18), + ), + Container( + height: 2, + ), + Text( + "ID:${user!.id!}", + style: TextStyle( + color: Color(0xFFA0A0A0), + fontSize: 12), + ) + ], )), Container( width: 5, @@ -379,31 +570,33 @@ Flex( direction: Axis.vertical, mainAxisAlignment: MainAxisAlignment.center, - children: [ - MyOutlineButton( - "鐢熸垚杞ㄨ抗", - 13, - height: 26, - width: 82, - fontSize: 12, - onClick: () { - print("鐢熸垚杞ㄨ抗"); - }, - ), - Container( - height: 6, - ), - MyOutlineButton( - "瀹炴椂鍏变韩", - 13, - height: 26, - width: 82, - fontSize: 12, - onClick: () { - print("瀹炴椂鍏变韩"); - }, - ), - ]) + children: user == null + ? [] + : [ + MyOutlineButton( + "鐢熸垚杞ㄨ抗", + 13, + height: 26, + width: 82, + fontSize: 12, + onClick: () { + print("鐢熸垚杞ㄨ抗"); + }, + ), + Container( + height: 6, + ), + MyOutlineButton( + "瀹炴椂鍏变韩", + 13, + height: 26, + width: 82, + fontSize: 12, + onClick: () { + print("瀹炴椂鍏变韩"); + }, + ), + ]) ], ) ], @@ -411,61 +604,200 @@ ), //鏇村 - Positioned( - left: MediaQuery.of(context).size.width / 2 - 10 - 70 / 2, - top: 80, - child: InkWell( - onTap: () { - setState(() { - locationInfoHidden = !locationInfoHidden; - }); - }, - child: Container( - width: 70, - height: 40, - child: Stack( - alignment: Alignment.bottomCenter, - children: [ - Container( - height: 30, - width: 60, - margin: EdgeInsets.only(top: 0), - alignment: Alignment.center, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: - BorderRadius.circular(15), - boxShadow: getViewShadow()), - ), - Positioned( - top: 0, - child: Container( - height: 25, - width: 70, - alignment: Alignment.bottomCenter, - + _location == null + ? Container() + : Positioned( + left: MediaQuery.of(context).size.width / 2 - + 10 - + 70 / 2, + top: 80, + child: InkWell( + onTap: () { + setState(() { + locationInfoHidden = !locationInfoHidden; + }); + }, + child: Container( + width: 70, + height: 40, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + Container( + height: 30, + width: 60, + margin: EdgeInsets.only(top: 0), + alignment: Alignment.center, decoration: BoxDecoration( - color: Colors.white, - ), - // child: Text( - // "鏀惰捣", - // style: TextStyle( - // color: ColorConstant.theme, - // fontSize: 11), - // ) - )), - Positioned( - bottom: 5, - child: Text( - locationInfoHidden ? "灞曞紑" : "鏀惰捣", - style: TextStyle( - color: ColorConstant.theme, - fontSize: 11), - )), - ])))) + color: Colors.white, + borderRadius: + BorderRadius.circular(15), + boxShadow: getViewShadow()), + ), + Positioned( + top: 0, + child: Container( + height: 25, + width: 70, + alignment: Alignment.bottomCenter, + + decoration: BoxDecoration( + color: Colors.white, + ), + // child: Text( + // "鏀惰捣", + // style: TextStyle( + // color: ColorConstant.theme, + // fontSize: 11), + // ) + )), + Positioned( + bottom: 5, + child: Text( + locationInfoHidden ? "灞曞紑" : "鏀惰捣", + style: TextStyle( + color: ColorConstant.theme, + fontSize: 11), + )), + ])))) ], )), ])); + } + + Widget _getStatus(LocationInviteStatus? status, LocationUserModel user) { + switch (status) { + case LocationInviteStatus.sentInvite: + return const Text( + "绛夊緟鍚屾剰", + style: TextStyle(color: ColorConstant.theme, fontSize: 15), + ); + + case LocationInviteStatus.agree: + return InkWell( + onTap: () { + Navigator.pop(context, user); + }, + child: Container( + padding: const EdgeInsets.only(left: 10, right: 10), + height: 25, + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: ColorConstant.theme), + borderRadius: BorderRadius.circular(10)), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset( + "assets/images/user/icon_user_location.png", + height: 15, + ), + Container( + width: 5, + ), + const Text( + "鍘诲畾浣�", + style: TextStyle(color: ColorConstant.theme, fontSize: 15), + ) + ], + ), + )); + case LocationInviteStatus.reject: + return const Text( + "瀵规柟鎷掓帴", + style: TextStyle(color: Color(0xFF9DAAB3), fontSize: 15), + ); + } + + return Container(); + } + + Image _getPortrait(LocationUserType? type) { + String img = "assets/images/user/"; + switch (type) { + case LocationUserType.father: + img += "icon_user_type_father.png"; + break; + case LocationUserType.mother: + img += "icon_user_type_mother.png"; + break; + case LocationUserType.husband: + img += "icon_user_type_husband.png"; + break; + case LocationUserType.wife: + img += "icon_user_type_wife.png"; + break; + case LocationUserType.daughter: + img += "icon_user_type_daughter.png"; + break; + case LocationUserType.son: + img += "icon_user_type_son.png"; + break; + case LocationUserType.other: + img += "icon_user_type_other.png"; + } + + return Image.asset( + img, + height: 31, + ); + } + + Widget _getUserItem(LocationUserModel user, int index) { + return Column(children: [ + Container( + padding: const EdgeInsets.fromLTRB(27, 0, 27, 0), + height: 80, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: index == 0 + ? const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10)) + : BorderRadius.zero), + child: Row( + children: [ + Container( + width: 40, + alignment: Alignment.center, + child: _getPortrait(user.userType), + ), + Container( + width: 8, + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + user.targetName!, + style: const TextStyle( + fontSize: 18, color: ColorConstant.theme), + ), + Container( + height: 5, + ), + Text( + user.targetPhone!, + style: + const TextStyle(fontSize: 15, color: Color(0xFF9DAAB3)), + ), + ], + )), + _getStatus(user.status, user) + ], + )), + Container( + height: 1, + color: Colors.white, + padding: const EdgeInsets.only(left: 27, right: 27), + child: Container( + color: const Color(0xFF9DAAB3), + ), + ) + ]); } Widget getPositionInfoView(BuildContext context) { @@ -493,9 +825,10 @@ decoration: BoxDecoration( color: const Color(0xFFCACDD3), borderRadius: BorderRadius.circular(20)), - child: const Text( - "2021.08.08 12:00", - style: TextStyle(color: Colors.white, fontSize: 10), + child: Text( + _location!.locTime!, + style: const TextStyle( + color: Colors.white, fontSize: 10), ), ), Container( @@ -508,14 +841,14 @@ "assets/images/main/icon_location_position_name.png", height: 16, ), - Text( + const Text( " 褰撳墠浣嶇疆锛�", style: TextStyle( color: Color(0xFF999999), fontSize: 12), ), Expanded( child: Text( - "閲嶅簡甯傞噸搴嗗競閲嶅簡甯傞噸搴嗗競閲嶅簡甯傞噸搴嗗競閲嶅簡甯傞噸搴嗗簡甯傞噸搴嗗競閲嶅簡", + _location!.address!, softWrap: false, overflow: TextOverflow.ellipsis, style: TextStyle( @@ -534,17 +867,17 @@ "assets/images/main/icon_location_position_location.png", height: 15, ), - Text( + const Text( " 缁� 绾� 搴︼細", style: TextStyle( color: Color(0xFF999999), fontSize: 12), ), Expanded( child: Text( - "N 41141.1233锛學 28741.389", + "N ${_location!.latitude!}锛學 ${_location!.longitude!}", softWrap: false, overflow: TextOverflow.ellipsis, - style: TextStyle( + style: const TextStyle( color: Color(0xFFBABABA), fontSize: 12), )) ], -- Gitblit v1.8.0