From 7baefdc45845d4da00726d212e57f91414bdea1d Mon Sep 17 00:00:00 2001 From: zhangmeng <494089941@qq.com> Date: Wed, 9 Mar 2022 13:45:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BB=BB=E5=8A=A1=E5=8F=91?= =?UTF-8?q?=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Runner/AppDelegate.swift | 1 + lib/pages/splash/splash_page.dart | 23 +- .../service/add_appointment_address_page.dart | 138 ++++++++++++ lib/ui/service/location_view.dart | 75 +++++++ lib/ui/service/publish_task_page.dart | 206 ++++++++++++------ lib/ui/service/task_func.dart | 51 +++-- lib/ui/service/task_remark_page.dart | 185 ++++++++++++---- lib/utils/hive_store.dart | 14 +- lib/widget/buttons/bee_long_button.dart | 26 +++ lib/widget/voice_player.dart | 3 +- pubspec.yaml | 1 + 11 files changed, 586 insertions(+), 137 deletions(-) create mode 100644 lib/ui/service/add_appointment_address_page.dart create mode 100644 lib/ui/service/location_view.dart create mode 100644 lib/widget/buttons/bee_long_button.dart diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index adc5e127..7383eba1 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -10,6 +10,7 @@ import Flutter // if #available(iOS 10.0, *) { // UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate // } + AMapServices.shared().apiKey ="84041703f7ecb242685325796897eff4" GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/pages/splash/splash_page.dart b/lib/pages/splash/splash_page.dart index 69c62db0..33023d3a 100644 --- a/lib/pages/splash/splash_page.dart +++ b/lib/pages/splash/splash_page.dart @@ -1,26 +1,26 @@ import 'dart:io'; +import 'package:aku_new_community/main_initialize.dart'; +import 'package:aku_new_community/pages/setting_page/agreement_page/agreement_page.dart'; +import 'package:aku_new_community/pages/setting_page/agreement_page/privacy_page.dart'; +import 'package:aku_new_community/provider/app_provider.dart'; +import 'package:aku_new_community/provider/user_provider.dart'; +import 'package:aku_new_community/utils/developer_util.dart'; +import 'package:aku_new_community/utils/headers.dart'; +import 'package:aku_new_community/utils/hive_store.dart'; +import 'package:aku_new_community/widget/others/user_tool.dart'; +import 'package:amap_flutter_location/amap_flutter_location.dart'; +// import 'package:amap_search_fluttify/amap_search_fluttify.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; - -import 'package:amap_flutter_location/amap_flutter_location.dart'; import 'package:get/get.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:power_logger/power_logger.dart'; import 'package:provider/provider.dart'; -import 'package:aku_new_community/main_initialize.dart'; -import 'package:aku_new_community/pages/setting_page/agreement_page/agreement_page.dart'; -import 'package:aku_new_community/pages/setting_page/agreement_page/privacy_page.dart'; -import 'package:aku_new_community/provider/app_provider.dart'; -import 'package:aku_new_community/provider/user_provider.dart'; -import 'package:aku_new_community/utils/developer_util.dart'; -import 'package:aku_new_community/utils/headers.dart'; -import 'package:aku_new_community/utils/hive_store.dart'; -import 'package:aku_new_community/widget/others/user_tool.dart'; import '../tab_navigator.dart'; class SplashPage extends StatefulWidget { @@ -48,6 +48,7 @@ class _SplashPageState extends State { final appProvider = Provider.of(context, listen: false); appProvider.initApplications(); appProvider.startLocation(); + // await AmapCore.init('84041703f7ecb242685325796897eff4'); if (HiveStore.appBox!.get('login') ?? false) { //更新用户信息后自动跳转首页/设置昵称/设置密码 await userProvider.setLogin(HiveStore.appBox!.get('token')); diff --git a/lib/ui/service/add_appointment_address_page.dart b/lib/ui/service/add_appointment_address_page.dart new file mode 100644 index 00000000..811f3b99 --- /dev/null +++ b/lib/ui/service/add_appointment_address_page.dart @@ -0,0 +1,138 @@ +import 'package:aku_new_community/utils/headers.dart'; +import 'package:aku_new_community/widget/bee_divider.dart'; +import 'package:aku_new_community/widget/bee_scaffold.dart'; +import 'package:aku_new_community/widget/buttons/bee_long_button.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class AddAppointmentAddressPage extends StatefulWidget { + const AddAppointmentAddressPage({Key? key}) : super(key: key); + + @override + _AddAppointmentAddressPageState createState() => + _AddAppointmentAddressPageState(); +} + +class _AddAppointmentAddressPageState extends State { + TextEditingController _controller = TextEditingController(); + TextEditingController _tagController = TextEditingController(); + + @override + void dispose() { + _controller.dispose(); + _tagController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return BeeScaffold( + title: '添加预约地址', + body: SafeArea( + child: ListView( + padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 32.w), + children: [ + Container( + width: double.infinity, + color: Colors.white, + padding: EdgeInsets.all(32.w), + child: Column( + children: [ + //TODO:封装高德search api插件 以获取poi数据 暂时手动输入 + // GestureDetector( + // onTap: () {}, + // child: Material( + // color: Colors.transparent, + // child: Row( + // children: [ + // SizedBox( + // width: 170.w, + // child: '所在地' + // .text + // .size(28.sp) + // .color(Colors.black.withOpacity(0.65)) + // .make(), + // ), + // '${S.of(context)?.tempPlotName}(默认)' + // .text + // .size(28.sp) + // .color(Colors.black.withOpacity(0.65)) + // .make(), + // ], + // ), + // ), + // ), + Row( + children: [ + SizedBox( + width: 170.w, + child: '标志建筑' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.65)) + .make(), + ), + Expanded( + child: TextField( + autofocus: false, + controller: _tagController, + decoration: InputDecoration( + border: InputBorder.none, + hintText: '请输入标志建筑', + contentPadding: EdgeInsets.zero, + isDense: true, + hintStyle: TextStyle( + color: Colors.black.withOpacity(0.45), + fontSize: 28.sp, + )), + )), + ], + ), + + 32.hb, + BeeDivider.horizontal(), + 32.hb, + Row( + children: [ + SizedBox( + width: 170.w, + child: '具体地址' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.65)) + .make(), + ), + Expanded( + child: TextField( + autofocus: false, + controller: _controller, + decoration: InputDecoration( + border: InputBorder.none, + hintText: '请输入具体地址', + contentPadding: EdgeInsets.zero, + isDense: true, + hintStyle: TextStyle( + color: Colors.black.withOpacity(0.45), + fontSize: 28.sp, + )), + )), + ], + ) + ], + ), + ), + 56.hb, + BeeLongButton( + onPressed: () { + Get.back(result: { + 'address': _tagController.text, + 'addressDetail': _controller.text, + }); + }, + text: '提交'), + ], + ), + ), + ); + } +} diff --git a/lib/ui/service/location_view.dart b/lib/ui/service/location_view.dart new file mode 100644 index 00000000..c07ffb1e --- /dev/null +++ b/lib/ui/service/location_view.dart @@ -0,0 +1,75 @@ +import 'package:aku_new_community/widget/bee_scaffold.dart'; +import 'package:aku_new_community/widget/others/bee_search_text_field.dart'; +import 'package:aku_new_community/widget/others/user_tool.dart'; +import 'package:amap_flutter_base/amap_flutter_base.dart'; +import 'package:amap_flutter_map/amap_flutter_map.dart'; +// import 'package:amap_search_fluttify/amap_search_fluttify.dart' as search; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; + +class LocationView extends StatefulWidget { + const LocationView({Key? key}) : super(key: key); + + @override + _LocationViewState createState() => _LocationViewState(); +} + +class _LocationViewState extends State { + AMapController? _mapController; + var poiList = []; + LatLng? _target; + + @override + void initState() { + Future.delayed(Duration(seconds: 0), () async { + var location = await Permission.locationWhenInUse.isGranted; + if (!location) { + await Permission.locationWhenInUse.request(); + } + _target = LatLng( + (UserTool.appProveider.location?['latitude'] ?? 0) as double, + (UserTool.appProveider.location?['longitude'] ?? 0) as double, + ); + // poiList = await search.AmapSearch.instance.searchAround(search.LatLng( + // (UserTool.appProveider.location?['latitude'] ?? 0) as double, + // (UserTool.appProveider.location?['longitude'] ?? 0) as double, + // )); + // print(poiList.length); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BeeScaffold( + title: BeeSearchTextField(), + body: Stack( + children: [ + AMapWidget( + privacyStatement: AMapPrivacyStatement( + hasContains: true, hasShow: true, hasAgree: true), + onMapCreated: (controller) { + // final appProvider = + // Provider.of(context, listen: false); + // LatLng _target = LatLng( + // (appProvider.location?['latitude'] ?? 0) as double, + // (appProvider.location?['longitude'] ?? 0) as double, + // ); + _mapController = controller; + _mapController!.moveCamera( + CameraUpdate.newCameraPosition( + CameraPosition(target: _target!, zoom: 18), + ), + ); + }, + myLocationStyleOptions: MyLocationStyleOptions( + true, + circleFillColor: Theme.of(context).primaryColor.withOpacity(0.2), + circleStrokeColor: Theme.of(context).primaryColor, + ), + ), + ], + ), + ); + } +} diff --git a/lib/ui/service/publish_task_page.dart b/lib/ui/service/publish_task_page.dart index 82c92e4d..787c93dc 100644 --- a/lib/ui/service/publish_task_page.dart +++ b/lib/ui/service/publish_task_page.dart @@ -1,13 +1,17 @@ import 'dart:io'; import 'package:aku_new_community/base/base_style.dart'; +import 'package:aku_new_community/constants/sars_api.dart'; import 'package:aku_new_community/gen/assets.gen.dart'; +import 'package:aku_new_community/ui/service/add_appointment_address_page.dart'; import 'package:aku_new_community/ui/service/task_func.dart'; import 'package:aku_new_community/ui/service/task_remark_page.dart'; import 'package:aku_new_community/utils/headers.dart'; +import 'package:aku_new_community/utils/network/net_util.dart'; import 'package:aku_new_community/widget/bee_divider.dart'; import 'package:aku_new_community/widget/bee_record_voice_widget.dart'; import 'package:aku_new_community/widget/bee_scaffold.dart'; +import 'package:aku_new_community/widget/buttons/bee_long_button.dart'; import 'package:aku_new_community/widget/picker/bee_date_picker.dart'; import 'package:aku_new_community/widget/picker/bee_pick_image_widget.dart'; import 'package:aku_new_community/widget/picker/bee_picker_box.dart'; @@ -29,28 +33,38 @@ class PublishTaskPage extends StatefulWidget { class _PublishTaskPageState extends State { List _types = ['跑腿', '代驾', '装修', '陪玩', '家政', '维修', '搬家', '家教', '其他']; + + //类型 int _type = 0; List _sexStr = ['男', '女', '不限']; int _sex = 0; + + //服务人员 int _service = 0; List _serviceObject = ['住户', '物业', '不限']; List _rewardTypes = ['赏金', '积分']; + + //报酬类型 int _rewardType = 0; - DateTime? _appointDate = DateTime.now(); - TextEditingController _titleController = TextEditingController(); - TextEditingController _addressController = TextEditingController(); + DateTime? _appointDate; + + DateTime? _appointEndDate; TextEditingController _rewardController = TextEditingController(); TextEditingController _nameController = TextEditingController(); TextEditingController _telController = TextEditingController(); String? _content; List _photos = []; String? _voiceUri; + String? _accessAddress; + String? _accessAddressDetail; + String? _serviceAddress; + String? _serviceAddressDetail; @override void dispose() { - _titleController.dispose(); - _addressController.dispose(); _rewardController.dispose(); + _nameController.dispose(); + _telController.dispose(); super.dispose(); } @@ -88,27 +102,45 @@ class _PublishTaskPageState extends State { ), bottomNavi: Padding( padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 32.w), - child: MaterialButton( - elevation: 0, - height: 93.w, - disabledColor: Colors.black.withOpacity(0.06), - disabledTextColor: Colors.black.withOpacity(0.25), - textColor: Colors.black.withOpacity(0.85), - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(65.w)), - color: kPrimaryColor, + child: BeeLongButton( onPressed: !canTap ? null : () async { var cancel = BotToast.showLoading(); + var _voiceUrl; + if (_voiceUri != null) { + try { + _voiceUrl = await NetUtil().upload( + SARSAPI.uploadFile.uploadImg, + File.fromUri(Uri(path: _voiceUri))); + } catch (e) { + print(e.toString()); + } + } + var imgs; + if (_photos.isNotEmpty) { + try { + imgs = await NetUtil() + .uploadFiles(_photos, SARSAPI.uploadFile.uploadImg); + } catch (e) { + print(e.toString()); + } + } var re = await TaskFunc.publish( - title: _titleController.text, - taskType: _type, - taskSex: _sex, - serviceObject: _service, - taskContent: _content ?? '', - taskDate: _appointDate.toString(), - taskAddress: _addressController.text, + type: _type, + sex: _sex, + servicePersonnel: _service, + readyStartTime: _appointDate.toString(), + readyEndTime: _appointEndDate.toString(), + contact: _nameController.text, + tel: _telController.text, + accessAddress: _accessAddress!, + accessAddressDetail: _accessAddressDetail!, + serviceAddress: _serviceAddress, + serviceAddressDetail: _serviceAddressDetail, + remarks: _content, + voiceUrl: _voiceUrl, + imgUrls: imgs, rewardType: _rewardType, reward: _rewardController.text); if (re) { @@ -116,7 +148,7 @@ class _PublishTaskPageState extends State { } cancel(); }, - child: '确认发布'.text.size(32.sp).bold.make(), + text: '确认发布', ), ), ); @@ -363,35 +395,57 @@ class _PublishTaskPageState extends State { } Container _dateAndAddress() { - var date = GestureDetector( - onTap: () async { - _appointDate = await BeeDatePicker.timePicker(DateTime.now()); - }, - child: Material( - color: Colors.transparent, - child: Row( - children: [ - SizedBox( - width: 170.w, - child: '预计时间' - .text - .size(28.sp) - .color(Colors.black.withOpacity(0.45)) - .make(), + var date = Row( + children: [ + SizedBox( + width: 170.w, + child: '预计时间' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.45)) + .make(), + ), + Expanded( + child: GestureDetector( + onTap: () async { + _appointDate = await BeeDatePicker.timePicker(DateTime.now()); + setState(() {}); + }, + child: Material( + color: Colors.transparent, + child: + '${DateUtil.formatDate(_appointDate, format: DateFormats.zh_mo_d_h_m)}' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.85)) + .make(), ), - '${DateUtil.formatDate(_appointDate)}' - .text - .size(28.sp) - .color(Colors.black.withOpacity(_type == 0 ? 0.25 : 0.85)) - .make(), - Spacer(), - Icon( - CupertinoIcons.chevron_right, - size: 24.w, + ), + ), + '-'.text.size(28.sp).color(Colors.black.withOpacity(0.85)).make(), + Expanded( + child: GestureDetector( + onTap: () async { + _appointEndDate = await BeeDatePicker.timePicker(DateTime.now()); + setState(() {}); + }, + child: Material( + color: Colors.transparent, + child: + '${DateUtil.formatDate(_appointEndDate, format: DateFormats.zh_mo_d_h_m)}' + .text + .size(28.sp) + .color(Colors.black.withOpacity(_type == 0 ? 0.25 : 0.85)) + .make(), ), - ], + ), ), - ), + Spacer(), + Icon( + CupertinoIcons.chevron_right, + size: 24.w, + ), + ], ); var contact = Row( children: [ @@ -476,7 +530,14 @@ class _PublishTaskPageState extends State { BeeDivider.horizontal(), 32.w.heightBox, GestureDetector( - onTap: () {}, + onTap: () async { + var re = await Get.to(() => AddAppointmentAddressPage()); + if (re != null) { + _accessAddress = re['address']; + _accessAddressDetail = re['addressDetail']; + setState(() {}); + } + }, child: Material( color: Colors.transparent, child: Row( @@ -508,7 +569,7 @@ class _PublishTaskPageState extends State { children: [ '鲍汁牛肉饭'.text.size(32.sp).black.bold.make(), 12.w.heightBox, - '江西省萍乡市莲花县良坊镇 19 幢 252 室daidjwoajdiowajdoiwa' + '${_accessAddress ?? ''}' .text .maxLines(1) .overflow(TextOverflow.ellipsis) @@ -545,7 +606,14 @@ class _PublishTaskPageState extends State { ], ), GestureDetector( - onTap: () {}, + onTap: () async { + var re = await Get.to(() => AddAppointmentAddressPage()); + if (re != null) { + _serviceAddress = re['address']; + _serviceAddressDetail = re['addressDetail']; + setState(() {}); + } + }, child: Material( color: Colors.transparent, child: Row( @@ -583,7 +651,7 @@ class _PublishTaskPageState extends State { .bold .make(), 12.w.heightBox, - '江西省萍乡市莲花县良坊镇 19 幢 252 室daidjwoajdiowajdoiwa' + '${_serviceAddress ?? ''}' .text .maxLines(1) .overflow(TextOverflow.ellipsis) @@ -628,6 +696,7 @@ class _PublishTaskPageState extends State { GestureDetector( onTap: () async { _content = await Get.to(() => TaskRemarkPage()); + setState(() {}); }, child: Material( color: Colors.transparent, @@ -641,13 +710,15 @@ class _PublishTaskPageState extends State { .color(Colors.black.withOpacity(0.45)) .make(), ), - '${_content == null ? '请输入任务备注' : _content}' - .text - .size(28.sp) - .color(Colors.black - .withOpacity(_rewardType == 0 ? 0.25 : 0.85)) - .make(), - Spacer(), + Expanded( + child: '${_content == null ? '请输入任务备注' : _content}' + .text + .size(28.sp) + .color(Colors.black + .withOpacity(_rewardType == 0 ? 0.25 : 0.85)) + .make(), + ), + 20.wb, Icon( CupertinoIcons.chevron_right, size: 24.w, @@ -861,10 +932,10 @@ class _PublishTaskPageState extends State { } bool get canTap { - if (_titleController.text.isEmpty) { + if (_type == 0) { return false; } - if (_type == 0) { + if (_service == 0) { return false; } if (_rewardType == 0) { @@ -876,15 +947,24 @@ class _PublishTaskPageState extends State { if (_appointDate == null) { return false; } - if (_content == null) { + if (_appointEndDate == null) { + return false; + } + if (_accessAddress == null) { return false; } - if (_addressController.text.isEmpty) { + if (_accessAddressDetail == null) { return false; } if (_rewardController.text.isEmpty) { return false; } + if (_nameController.text.isEmpty) { + return false; + } + if (_telController.text.isEmpty) { + return false; + } return true; } diff --git a/lib/ui/service/task_func.dart b/lib/ui/service/task_func.dart index 7ac6ab51..c9a3beb7 100644 --- a/lib/ui/service/task_func.dart +++ b/lib/ui/service/task_func.dart @@ -4,26 +4,41 @@ import 'package:aku_new_community/utils/network/net_util.dart'; class TaskFunc { ///确认发布 - static Future publish( - {required String title, - required int taskType, - required int taskSex, - required int serviceObject, - required String taskContent, - required String taskDate, - required String taskAddress, - required int rewardType, - required String reward}) async { + static Future publish({ + required int type, + required int sex, + required int servicePersonnel, + required String readyStartTime, + required String readyEndTime, + required String contact, + required String tel, + required String accessAddress, + required String accessAddressDetail, + required String? serviceAddress, + required String? serviceAddressDetail, + required String? remarks, + required String voiceUrl, + required List imgUrls, + required int rewardType, + required String reward, + }) async { var base = await NetUtil().post(API.manager.task.publish, params: { - 'title': title, - 'taskType': taskType, - 'taskSex': taskSex, - 'serviceObject': serviceObject, - 'taskContent': taskContent, - 'taskDate': taskDate, - 'taskAddress': taskAddress, + 'type': type, + 'sex': sex, + 'servicePersonnel': servicePersonnel, + 'readyStartTime': readyStartTime, + 'readyEndTime': readyEndTime, + 'contact': contact, + 'tel': tel, + 'accessAddress': accessAddress, + 'accessAddressDetail': accessAddressDetail, + 'serviceAddress': serviceAddress, + 'serviceAddressDetail': serviceAddressDetail, + 'remarks': remarks, + 'voiceUrl': voiceUrl, + 'imgUrls': imgUrls, 'rewardType': rewardType, - 'reward': int.parse(reward), + 'reward': reward, }); return base.success; } diff --git a/lib/ui/service/task_remark_page.dart b/lib/ui/service/task_remark_page.dart index 69718978..197f7996 100644 --- a/lib/ui/service/task_remark_page.dart +++ b/lib/ui/service/task_remark_page.dart @@ -1,10 +1,11 @@ -import 'package:aku_new_community/base/base_style.dart'; +import 'package:aku_new_community/utils/hive_store.dart'; import 'package:aku_new_community/widget/bee_scaffold.dart'; +import 'package:aku_new_community/widget/buttons/bee_long_button.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:velocity_x/src/extensions/num_ext.dart'; -import 'package:velocity_x/src/extensions/string_ext.dart'; +import 'package:velocity_x/velocity_x.dart'; class TaskRemarkPage extends StatefulWidget { const TaskRemarkPage({Key? key}) : super(key: key); @@ -15,6 +16,14 @@ class TaskRemarkPage extends StatefulWidget { class _TaskRemarkPageState extends State { TextEditingController _contentController = TextEditingController(); + List _shortcutLabel = []; + bool _edit = false; + + @override + void initState() { + _shortcutLabel = HiveStore.shortcutBox!.values.cast().toList(); + super.initState(); + } @override void dispose() { @@ -29,54 +38,152 @@ class _TaskRemarkPageState extends State { body: ListView( padding: EdgeInsets.all(32.w), children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - '任务内容' - .text - .size(28.sp) - .color(Colors.black.withOpacity(0.45)) - .make(), - ], - ), - 32.w.heightBox, Container( - width: double.infinity, - padding: EdgeInsets.symmetric(horizontal: 24.w), + padding: EdgeInsets.all(32.w), decoration: BoxDecoration( - color: Colors.black.withOpacity(0.06), - borderRadius: BorderRadius.circular(16.w)), - child: TextField( - controller: _contentController, - autofocus: false, - onChanged: (text) => setState(() {}), - minLines: 5, - maxLength: 200, - maxLines: 20, - decoration: InputDecoration( - border: InputBorder.none, - ), + color: Colors.white, borderRadius: BorderRadius.circular(16.w)), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + '任务内容' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.45)) + .make(), + ], + ), + 32.w.heightBox, + Container( + width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 24.w), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.06), + borderRadius: BorderRadius.circular(16.w)), + child: TextField( + controller: _contentController, + autofocus: false, + onChanged: (text) => setState(() {}), + minLines: 5, + maxLength: 200, + maxLines: 20, + decoration: InputDecoration( + border: InputBorder.none, + ), + ), + ), + 32.w.heightBox, + Row( + children: [ + '快捷标签' + .text + .size(24.sp) + .color(Colors.black.withOpacity(0.45)) + .make(), + Spacer(), + GestureDetector( + onTap: () { + _edit = !_edit; + setState(() {}); + }, + child: Material( + color: Colors.transparent, + child: Row( + children: [ + '${_edit ? '保存' : '编辑'}' + .text + .size(24.sp) + .color(Colors.black.withOpacity(0.45)) + .make(), + ], + ), + ), + ), + ], + ), + 32.w.heightBox, + Wrap( + spacing: 12.w, + runSpacing: 12.w, + children: _shortcutLabel + .mapIndexed((currentValue, index) => + label(currentValue, _edit, index)) + .toList(), + ), + ], ), - ) + ), ], ), bottomNavi: Padding( padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 32.w), - child: MaterialButton( - elevation: 0, - height: 93.w, - disabledColor: Colors.black.withOpacity(0.06), - disabledTextColor: Colors.black.withOpacity(0.25), - textColor: Colors.black.withOpacity(0.85), - shape: - RoundedRectangleBorder(borderRadius: BorderRadius.circular(65.w)), - color: kPrimaryColor, + child: BeeLongButton( onPressed: () async { + var inBox = _shortcutLabel.contains(_contentController.text); + if (!inBox&&_contentController.text.isNotEmpty) { + await HiveStore.shortcutBox!.add(_contentController.text); + } Get.back(result: _contentController.text); }, - child: '完成'.text.size(32.sp).bold.make(), + text: '完成', ), ), ); } + + Widget label(String text, bool edit, int index) { + var textHandled = ''; + if (text.length > 10) { + textHandled = text.replaceRange(10, null, '…'); + } else { + textHandled = text; + } + return Stack( + clipBehavior: Clip.none, + children: [ + GestureDetector( + onTap: () { + _contentController.text = text; + setState(() {}); + }, + child: Material( + color: Colors.transparent, + child: FittedBox( + child: Container( + height: 60.w, + padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 8.w), + alignment: Alignment.center, + decoration: BoxDecoration( + border: Border.all(color: Colors.black.withOpacity(0.25)), + borderRadius: BorderRadius.circular(8.w)), + child: textHandled.text + .size(22.sp) + .color(Colors.black.withOpacity(0.45)) + .make(), + ), + ), + ), + ), + if (edit) + Positioned( + top: -10.w, + right: -10.w, + child: GestureDetector( + onTap: () { + _shortcutLabel.removeAt(index); + HiveStore.shortcutBox!.deleteAt(index); + setState(() {}); + }, + child: Material( + child: Icon( + CupertinoIcons.xmark_circle_fill, + size: 40.w, + color: Colors.black.withOpacity(0.45), + ), + ), + )) + ], + ); + } } diff --git a/lib/utils/hive_store.dart b/lib/utils/hive_store.dart index 7b76ac02..b4723b56 100644 --- a/lib/utils/hive_store.dart +++ b/lib/utils/hive_store.dart @@ -1,21 +1,24 @@ -import 'package:flutter/foundation.dart'; - -import 'package:hive/hive.dart'; -import 'package:path_provider/path_provider.dart'; - import 'package:aku_new_community/model/user/province_model.dart'; import 'package:aku_new_community/models/login/china_region_model.dart'; import 'package:aku_new_community/models/login/history_login_model.dart'; import 'package:aku_new_community/models/user/user_config_model.dart'; +import 'package:flutter/foundation.dart'; +import 'package:hive/hive.dart'; +import 'package:path_provider/path_provider.dart'; class HiveStore { static Box? _appBox; static Box? get appBox => _appBox; static Box? _userBox; + static Box? get userBox => _userBox; static Box? _dataBox; + static Box? get dataBox => _dataBox; + static Box? _shortcutBox; + + static Box? get shortcutBox => _dataBox; static Future init() async { if (!kIsWeb) { @@ -30,6 +33,7 @@ class HiveStore { _appBox = await Hive.openBox('app'); _userBox = await Hive.openBox('userBox'); _dataBox = await Hive.openBox('dataBox'); + _shortcutBox = await Hive.openBox('shortcut'); } } } diff --git a/lib/widget/buttons/bee_long_button.dart b/lib/widget/buttons/bee_long_button.dart new file mode 100644 index 00000000..8e3a080a --- /dev/null +++ b/lib/widget/buttons/bee_long_button.dart @@ -0,0 +1,26 @@ +import 'package:aku_new_community/base/base_style.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:velocity_x/src/extensions/string_ext.dart'; + +class BeeLongButton extends StatelessWidget { + final VoidCallback? onPressed; + final String text; + const BeeLongButton({Key? key, required this.onPressed, required this.text}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialButton( + elevation: 0, + height: 93.w, + disabledColor: Colors.black.withOpacity(0.06), + disabledTextColor: Colors.black.withOpacity(0.25), + textColor: Colors.black.withOpacity(0.85), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(65.w)), + color: kPrimaryColor, + onPressed: onPressed, + child: text.text.size(32.sp).bold.make(), + ); + } +} diff --git a/lib/widget/voice_player.dart b/lib/widget/voice_player.dart index c5eae92f..9e4d8dd2 100644 --- a/lib/widget/voice_player.dart +++ b/lib/widget/voice_player.dart @@ -124,7 +124,8 @@ class _VoicePlayerState extends State @override void dispose() { - stopPlay(); + _timer?.cancel(); + _timer = null; player.dispose(); controller.dispose(); animation.removeListener(() {}); diff --git a/pubspec.yaml b/pubspec.yaml index 76bfb278..5d0ccad3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -86,6 +86,7 @@ dependencies: amap_flutter_map: ^3.0.0 amap_flutter_location: ^3.0.0 amap_flutter_base: ^3.0.0 +# amap_search_fluttify: 0.17.0-dev.0 #动态文字 animated_text_kit: ^4.2.1 #分享功能