diff --git a/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart b/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart index 6ce5fb16..c32e8d6e 100644 --- a/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart +++ b/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_logic.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; +import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_page.dart'; import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_state.dart'; import 'package:star_lock/main/lockDetail/lockOperatingRecord/lockOperatingRecordGetLastRecordTime_entity.dart'; import 'package:star_lock/tools/toast.dart'; diff --git a/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_page.dart b/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_page.dart index b978f8e0..5e48eb49 100644 --- a/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_page.dart +++ b/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_page.dart @@ -1,13 +1,13 @@ +import 'package:cupertino_stepper/cupertino_stepper.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_advanced_calendar/flutter_advanced_calendar.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:gzx_dropdown_menu/gzx_dropdown_menu.dart'; import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_logic.dart'; -import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart'; import '../../../app_settings/app_colors.dart'; -import '../../../tools/custom_bottom_sheet.dart'; -import '../../../tools/noData.dart'; import '../../../tools/storage.dart'; import '../../../tools/titleAppBar.dart'; import '../../../tools/toast.dart'; @@ -24,8 +24,15 @@ class _DoorLockLogPageState extends State { final logic = Get.put(DoorLockLogLogic()); final state = Get.find().state; + @override + void initState() { + super.initState(); + } + @override Widget build(BuildContext context) { + final theme = Theme.of(context); + return Scaffold( backgroundColor: AppColors.mainBackgroundColor, appBar: TitleAppBar( @@ -42,21 +49,6 @@ class _DoorLockLogPageState extends State { onPressed: () async { var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); if (isDemoMode == false) { - // JhPopMenus.showLinePop(context, clickCallback: (index, selText) { - // print('选中index: $index'); - // print('选中text: $selText'); - // if (index == 0) { - // logic.mockNetworkDataRequest(); - // } else if (index == 1) { - // logic.clearOperationRecordRequest(); - // } - // }, listData: [ - // {'text': '读取记录'}, - // {'text': '清空记录'}, - // {'text': '导出记录'}, - // ]); - - _openModalBottomSheet(); } else { // Get.toNamed(Routers.seletLockTypePage); Toast.show(msg: "演示模式"); @@ -67,76 +59,268 @@ class _DoorLockLogPageState extends State { ), body: SingleChildScrollView( child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - AdvancedCalendar( - controller: state.calendarControllerCustom, - events: state.events, - weekLineHeight: 50.0.h, - startWeekDay: 1, - innerDot: true, - keepLineSize: true, - calendarTextStyle: TextStyle( - fontSize: 22.sp, - fontWeight: FontWeight.w500, - height: 1.3125, - letterSpacing: 0, + Theme( + data: theme.copyWith( + textTheme: theme.textTheme.copyWith( + titleMedium: theme.textTheme.titleMedium!.copyWith( + fontSize: 16, + color: theme.colorScheme.secondary, + ), + bodyLarge: theme.textTheme.bodyLarge!.copyWith( + fontSize: 14, + color: Colors.black54, + ), + bodyMedium: theme.textTheme.bodyMedium!.copyWith( + fontSize: 12, + color: Colors.black87, + ), + ), + primaryColor: AppColors.mainColor, + highlightColor: Colors.yellow, + disabledColor: Colors.green, ), - headerStyle: TextStyle( - fontSize: 22.sp, - fontWeight: FontWeight.w500, - height: 1.3125, - letterSpacing: 0, + child: AdvancedCalendar( + controller: state.calendarControllerCustom, + events: state.events, + weekLineHeight: 48.0, + startWeekDay: 1, + innerDot: true, + keepLineSize: true, + calendarTextStyle: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w400, + height: 1.3125, + letterSpacing: 0, + ), ), ), + Stack( + key: state.stackKey, + children: [ + Column( + children: [ + _buildHeaderView(), + ], + ), + // 下拉菜单,注意GZXDropDownMenu目前只能在Stack内,后续有时间会改进,以及支持CustomScrollView和NestedScrollView + _buildDropDownMenu() + ], + ), + OrientationBuilder( + builder: (BuildContext context, Orientation orientation) { + switch (orientation) { + case Orientation.portrait: + return _buildStepper(StepperType.vertical); + case Orientation.landscape: + return _buildStepper(StepperType.horizontal); + default: + throw UnimplementedError(orientation.toString()); + } + }, + ), ], ), ), ); } - String getTypeIcon(int type) { - String title = 'images/controls_user.png'; - switch (type) { - case 1: - // 蓝牙开锁 - title = 'images/controls_user.png'; - break; - case 4: - // 密码开锁 - title = 'images/icon_password.png'; - break; - case 7: - // ic卡 - title = 'images/icon_card.png'; - break; - case 8: - // 指纹开锁 - title = 'images/icon_fingerprint.png'; - break; - default: - break; - } - return title; +//下拉头部控件GZXDropDownHeader + Widget _buildHeaderView() { + return GZXDropDownHeader( + // 下拉的头部项,目前每一项,只能自定义显示的文字、图标、图标大小修改 + items: [ + GZXDropDownHeaderItem(state.dropDownDoorLockItem[0], iconSize: 36), + ], + // GZXDropDownHeader对应第一父级Stack的key + stackKey: state.stackKey, + // controller用于控制menu的显示或隐藏 + controller: state.dropdownMenuController, + // 当点击头部项的事件,在这里可以进行页面跳转或openEndDrawer + onItemTap: (index) {}, + // 头部的高度 + height: 46, + // 头部背景颜色 + color: Colors.white, + // 文字样式 + style: TextStyle( + color: AppColors.darkGrayTextColor, fontSize: ScreenUtil().setSp(24)), + // 下拉时文字样式 + dropDownStyle: TextStyle( + fontSize: ScreenUtil().setSp(24), + color: AppColors.darkGrayTextColor, + ), + // 图标大小 + iconSize: 20, + // 图标颜色 + iconColor: AppColors.greyBackgroundColor, + // 下拉时图标颜色 + iconDropDownColor: AppColors.mainColor, + ); } - Future _openModalBottomSheet() async { - showModalBottomSheet( - context: context, - shape: RoundedRectangleBorder( - borderRadius: BorderRadiusDirectional.circular(10)), - builder: (BuildContext context) { - return AlertBottomWidget( - topTitle: '', - items: const ['读取记录', '清空记录', '导出记录'], - chooseCallback: (value) { - int getSelectIndex = value; - if (getSelectIndex == 0) { - logic.mockNetworkDataRequest(); - } else if (getSelectIndex == 1) { - logic.clearOperationRecordRequest(); - } - }, - ); - }); + //下拉菜单 + Widget _buildDropDownMenu() { + return Obx(() => GZXDropDownMenu( + // controller用于控制menu的显示或隐藏 + controller: state.dropdownMenuController, + // 下拉菜单显示或隐藏动画时长 + animationMilliseconds: 300, + // 下拉后遮罩颜色 +// maskColor: Theme.of(context).primaryColor.withOpacity(0.5), +// maskColor: Colors.red.withOpacity(0.5), + dropdownMenuChanging: (isShow, index) {}, + dropdownMenuChanged: (isShow, index) {}, + // 下拉菜单,高度自定义,你想显示什么就显示什么,完全由你决定,你只需要在选择后调用_dropdownMenuController.hide();即可 + menus: [ + GZXDropdownMenuBuilder( + dropDownHeight: 44.0.h * state.eventSortConditions.value.length, + dropDownWidget: _buildConditionListWidget( + state.eventSortConditions.value, (value) { + state.selectGroupSortCondition = value; + state.dropDownDoorLockItem[0] = + state.selectGroupSortCondition.name; + })), + ], + )); + } + + _buildConditionListWidget( + items, void Function(SortCondition sortCondition) itemOnTap) { + return Container( + color: Colors.white, + child: ListView.separated( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + scrollDirection: Axis.vertical, + itemCount: items.length, + // item 的个数 + separatorBuilder: (BuildContext context, int index) => + const Divider(height: 1.0), + // 添加分割线 + itemBuilder: (BuildContext context, int index) { + return gestureDetector(items, index, itemOnTap, context); + }, + ), + ); + } + + GestureDetector gestureDetector( + items, + int index, + void Function(SortCondition sortCondition) itemOnTap, + BuildContext context) { + SortCondition goodsSortCondition = items[index]; + return GestureDetector( + onTap: () { + for (var value in items) { + value.isSelected = false; + } + goodsSortCondition.isSelected = true; + + itemOnTap(goodsSortCondition); + }, + child: SizedBox( + height: 44.h, + child: Center( + child: Obx(() => Text( + goodsSortCondition.name, + style: TextStyle( + color: goodsSortCondition.isSelected + ? AppColors.mainColor + : Colors.black, + ), + )), + ), + )); + } + + CupertinoStepper _buildStepper(StepperType type) { + final canCancel = state.currentStep.value > 0; + final canContinue = state.currentStep.value < 3; + return CupertinoStepper( + type: type, + currentStep: state.currentStep.value, + onStepTapped: (step) => setState(() => state.currentStep.value = step), + onStepCancel: + canCancel ? () => setState(() => --state.currentStep.value) : null, + onStepContinue: + canContinue ? () => setState(() => ++state.currentStep.value) : null, + steps: [ + for (var i = 0; i < 3; ++i) + _buildStep( + title: const Text(''), + isActive: i == state.currentStep.value, + state: i == state.currentStep.value + ? StepState.editing + : i < state.currentStep.value + ? StepState.complete + : StepState.indexed, + ), + // _buildStep( + // title: Text('Error'), + // state: StepState.error, + // ), + // _buildStep( + // title: Text('Disabled'), + // state: StepState.disabled, + // ) + ], + ); + } + + Step _buildStep({ + required Widget title, + StepState state = StepState.indexed, + bool isActive = false, + }) { + return Step( + title: title, + subtitle: const Text('10:45 有人出现在门口'), + state: state, + isActive: isActive, + content: LimitedBox( + maxWidth: 300, + maxHeight: 300, + child: Container(color: CupertinoColors.systemGrey), + ), + ); } } + +String getTypeIcon(int type) { + String title = 'images/controls_user.png'; + switch (type) { + case 1: + // 蓝牙开锁 + title = 'images/controls_user.png'; + break; + case 4: + // 密码开锁 + title = 'images/icon_password.png'; + break; + case 7: + // ic卡 + title = 'images/icon_card.png'; + break; + case 8: + // 指纹开锁 + title = 'images/icon_fingerprint.png'; + break; + default: + break; + } + return title; +} + +class SortCondition { + String name; + bool isSelected; + + SortCondition({ + required this.name, + required this.isSelected, + }); +} diff --git a/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_state.dart b/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_state.dart index a2566e5b..e3ac177f 100644 --- a/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_state.dart +++ b/star_lock/lib/main/lockDetail/doorLockLog/doorLockLog_state.dart @@ -1,5 +1,8 @@ +import 'package:flutter/material.dart'; import 'package:flutter_advanced_calendar/flutter_advanced_calendar.dart'; import 'package:get/get.dart'; +import 'package:gzx_dropdown_menu/gzx_dropdown_menu.dart'; +import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_page.dart'; import '../../lockMian/entity/lockListInfo_entity.dart'; import '../electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart'; @@ -9,11 +12,25 @@ class DoorLockLogState { final lockOperatingRecordListData = [].obs; final calendarControllerToday = AdvancedCalendarController.today(); final calendarControllerCustom = - AdvancedCalendarController(DateTime(2024, 01, 09)); + AdvancedCalendarController(DateTime(2024, 01, 10)); final events = [ DateTime.now(), DateTime(2024, 10, 10), ]; + final eventSortConditions = [ + SortCondition(name: '全部事件', isSelected: true), + SortCondition(name: '门锁异常', isSelected: false), + SortCondition(name: '有人出现', isSelected: false), + SortCondition(name: '有人按门铃', isSelected: false), + SortCondition(name: '一次性密码开门', isSelected: false) + ].obs; + final List dropDownDoorLockItem = ['全部事件']; + final GZXDropdownMenuController dropdownMenuController = + GZXDropdownMenuController(); + final scaffoldKey = GlobalKey(); + final GlobalKey stackKey = GlobalKey(); + late SortCondition selectGroupSortCondition = eventSortConditions.value[0]; + var currentStep = 0.obs; DoorLockLogState() { keyInfos.value = Get.arguments["keyInfo"]; diff --git a/star_lock/lib/main/lockDetail/realTimePicture/realTimePicture_page.dart b/star_lock/lib/main/lockDetail/realTimePicture/realTimePicture_page.dart index 4bbdba35..eed5ab49 100644 --- a/star_lock/lib/main/lockDetail/realTimePicture/realTimePicture_page.dart +++ b/star_lock/lib/main/lockDetail/realTimePicture/realTimePicture_page.dart @@ -27,6 +27,11 @@ class _RealTimePicturePageState extends State void initState() { super.initState(); + //写一个定时器,三十秒后页面自动返回 + Timer(const Duration(seconds: 30), () { + Get.back(); + }); + state.animationController = AnimationController(duration: const Duration(seconds: 1), vsync: this); state.animationController.repeat(); @@ -373,6 +378,7 @@ class _RealTimePicturePageState extends State void _handleFailure() { // 在这里处理失败的逻辑 state.animationController.stop(); + state.realTimePicTimer.cancel(); } @override diff --git a/star_lock/lib/talk/udp/udp_reciverData.dart b/star_lock/lib/talk/udp/udp_reciverData.dart index 8357107b..5ca238b0 100644 --- a/star_lock/lib/talk/udp/udp_reciverData.dart +++ b/star_lock/lib/talk/udp/udp_reciverData.dart @@ -197,16 +197,16 @@ class CommandUDPReciverManager { // 对方结束监视 print("对方结束监视"); } else { - //结束对讲反馈 + //结束监视反馈 print("结束监视反馈"); } - Toast.show(msg: "对方已结束监视"); - UDPTalkClass().status = 0; - UDPTalkClass().isBeCall = false; - UDPTalkClass().stopLocalAudio(); - CallTalk().stopPcmSound(); - eventBus.fire(GetUDPStatusRefreshUI(UDPTalkClass().status)); - Get.back(); + // Toast.show(msg: "对方已结束监视"); + // UDPTalkClass().status = 0; + // UDPTalkClass().isBeCall = false; + // UDPTalkClass().stopLocalAudio(); + // CallTalk().stopPcmSound(); + // eventBus.fire(GetUDPStatusRefreshUI(UDPTalkClass().status)); + // Get.back(); } break; default: diff --git a/star_lock/pubspec.yaml b/star_lock/pubspec.yaml index 8de9c333..5b47df22 100644 --- a/star_lock/pubspec.yaml +++ b/star_lock/pubspec.yaml @@ -135,6 +135,9 @@ dependencies: #监听网络连接状态 connectivity_plus: ^5.0.2 flutter_advanced_calendar: ^1.4.1 + #下拉选择菜单框 + gzx_dropdown_menu: ^3.1.0 + cupertino_stepper: ^0.2.1 dev_dependencies: flutter_test: