解决时间选择器 确定按钮不显示问题
This commit is contained in:
parent
f5e978e32c
commit
3db1afb244
@ -1,12 +1,14 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/network/api_repository.dart';
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/storage.dart';
|
import 'package:star_lock/tools/storage.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
@ -327,9 +329,9 @@ class _AuthorizedAdminPageState extends State<AuthorizedAdminPage> {
|
|||||||
|
|
||||||
var entity = await ApiRepository.to.setRoomStatusData(
|
var entity = await ApiRepository.to.setRoomStatusData(
|
||||||
lockId: state.keyInfo.value.lockId!,
|
lockId: state.keyInfo.value.lockId!,
|
||||||
roomStatus:1,
|
roomStatus: 1,
|
||||||
);
|
);
|
||||||
if(entity.errorCode!.codeIsSuccessful){
|
if (entity.errorCode!.codeIsSuccessful) {
|
||||||
print("标记为已入住成功啦啦啦啦啦");
|
print("标记为已入住成功啦啦啦啦啦");
|
||||||
Toast.show(msg: "标记成功");
|
Toast.show(msg: "标记成功");
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/app_settings/app_colors.dart';
|
import 'package:star_lock/app_settings/app_colors.dart';
|
||||||
import 'package:star_lock/network/api_repository.dart';
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
import '../../../../appRouters.dart';
|
import '../../../../appRouters.dart';
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
import '../../../../appRouters.dart';
|
import '../../../../appRouters.dart';
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
@ -16,13 +17,18 @@ import '../../../../translations/trans_lib.dart';
|
|||||||
import 'addCardType_logic.dart';
|
import 'addCardType_logic.dart';
|
||||||
|
|
||||||
class AddCardPage extends StatefulWidget {
|
class AddCardPage extends StatefulWidget {
|
||||||
final String seletType;// 永久限时循环下标
|
final String seletType; // 永久限时循环下标
|
||||||
final int lockId;
|
final int lockId;
|
||||||
final int fromType;// // 1从添加钥匙列表进入 2从考勤添加员工入口进入
|
final int fromType; // // 1从添加钥匙列表进入 2从考勤添加员工入口进入
|
||||||
final String fromTypeTwoStaffName;// 从添加员工进入 传入员工名字
|
final String fromTypeTwoStaffName; // 从添加员工进入 传入员工名字
|
||||||
|
|
||||||
const AddCardPage(
|
const AddCardPage(
|
||||||
{Key? key, required this.seletType, required this.lockId, required this.fromType, required this.fromTypeTwoStaffName}) : super(key: key);
|
{Key? key,
|
||||||
|
required this.seletType,
|
||||||
|
required this.lockId,
|
||||||
|
required this.fromType,
|
||||||
|
required this.fromTypeTwoStaffName})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AddCardPage> createState() => _AddCardPageState();
|
State<AddCardPage> createState() => _AddCardPageState();
|
||||||
@ -52,8 +58,10 @@ class _AddCardPageState extends State<AddCardPage> {
|
|||||||
// return sendElectronicKeySucceed();
|
// return sendElectronicKeySucceed();
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -63,8 +71,10 @@ class _AddCardPageState extends State<AddCardPage> {
|
|||||||
// 限时
|
// 限时
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
keyTimeLimitWidget(),
|
keyTimeLimitWidget(),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
@ -76,18 +86,24 @@ class _AddCardPageState extends State<AddCardPage> {
|
|||||||
// 循环
|
// 循环
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
CommonItem(
|
CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr,
|
leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr,
|
||||||
rightTitle: "",
|
rightTitle: "",
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
action: () async {
|
action: () async {
|
||||||
Map result = await Get.toNamed(Routers.electronicKeyPeriodValidityPage);
|
Map result = await Get.toNamed(
|
||||||
|
Routers.electronicKeyPeriodValidityPage);
|
||||||
state.weekdaysList.value = result['validityValue'];
|
state.weekdaysList.value = result['validityValue'];
|
||||||
state.effectiveDateTime.value = result['starDate'].millisecondsSinceEpoch;
|
state.effectiveDateTime.value =
|
||||||
state.failureDateTime.value = result['endDate'].millisecondsSinceEpoch;
|
result['starDate'].millisecondsSinceEpoch;
|
||||||
print('得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}');
|
state.failureDateTime.value =
|
||||||
|
result['endDate'].millisecondsSinceEpoch;
|
||||||
|
print(
|
||||||
|
'得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}');
|
||||||
}),
|
}),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
@ -127,13 +143,17 @@ class _AddCardPageState extends State<AddCardPage> {
|
|||||||
action: () async {
|
action: () async {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.beginTime.value = '${p.year}-${p.month!.toString().padLeft(2,'0')}-${p.day!.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}';
|
state.beginTime.value =
|
||||||
state.beginTimeTimestamp.value = DateTime.parse(state.beginTime.value).millisecondsSinceEpoch.toString();
|
'${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}';
|
||||||
});
|
state.beginTimeTimestamp.value =
|
||||||
});
|
DateTime.parse(state.beginTime.value)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
||||||
@ -142,13 +162,17 @@ class _AddCardPageState extends State<AddCardPage> {
|
|||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.endTime.value = '${p.year}-${p.month!.toString().padLeft(2,'0')}-${p.day!.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}';
|
state.endTime.value =
|
||||||
state.endTimeTimestamp.value = DateTime.parse(state.endTime.value).millisecondsSinceEpoch.toString();
|
'${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}';
|
||||||
});
|
state.endTimeTimestamp.value =
|
||||||
});
|
DateTime.parse(state.endTime.value)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Container(height: 10.h),
|
Container(height: 10.h),
|
||||||
],
|
],
|
||||||
@ -166,23 +190,23 @@ class _AddCardPageState extends State<AddCardPage> {
|
|||||||
rightWidget: SizedBox(
|
rightWidget: SizedBox(
|
||||||
width: 60.w, height: 50.h, child: _isStressFingerprint())),
|
width: 60.w, height: 50.h, child: _isStressFingerprint())),
|
||||||
SizedBox(height: 30.h),
|
SizedBox(height: 30.h),
|
||||||
SubmitBtn(btnName: TranslationLoader.lanKeys!.next!.tr, onClick: () async {
|
SubmitBtn(
|
||||||
|
btnName: TranslationLoader.lanKeys!.next!.tr,
|
||||||
|
onClick: () async {
|
||||||
|
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
||||||
|
if (isDemoMode == false) {
|
||||||
|
// print("state.seletType:${state.seletType.value}");
|
||||||
|
if (state.nameController.text.isEmpty) {
|
||||||
|
Toast.show(msg: "请输入姓名");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
logic.addCardData();
|
||||||
if(isDemoMode == false){
|
} else {
|
||||||
// print("state.seletType:${state.seletType.value}");
|
// Get.toNamed(Routers.seletLockTypePage);
|
||||||
if(state.nameController.text.isEmpty){
|
Toast.show(msg: "演示模式");
|
||||||
Toast.show(msg: "请输入姓名");
|
}
|
||||||
return;
|
}),
|
||||||
}
|
|
||||||
|
|
||||||
logic.addCardData();
|
|
||||||
}else{
|
|
||||||
// Get.toNamed(Routers.seletLockTypePage);
|
|
||||||
Toast.show(msg: "演示模式");
|
|
||||||
}
|
|
||||||
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -322,5 +346,4 @@ class _AddCardPageState extends State<AddCardPage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
import '../../../../tools/commonItem.dart';
|
import '../../../../tools/commonItem.dart';
|
||||||
@ -15,10 +16,12 @@ class OtherTypeKeyChangeDatePage extends StatefulWidget {
|
|||||||
const OtherTypeKeyChangeDatePage({Key? key}) : super(key: key);
|
const OtherTypeKeyChangeDatePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<OtherTypeKeyChangeDatePage> createState() => _OtherTypeKeyChangeDatePageState();
|
State<OtherTypeKeyChangeDatePage> createState() =>
|
||||||
|
_OtherTypeKeyChangeDatePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _OtherTypeKeyChangeDatePageState extends State<OtherTypeKeyChangeDatePage> {
|
class _OtherTypeKeyChangeDatePageState
|
||||||
|
extends State<OtherTypeKeyChangeDatePage> {
|
||||||
final logic = Get.put(OtherTypeKeyChangeDateLogic());
|
final logic = Get.put(OtherTypeKeyChangeDateLogic());
|
||||||
final state = Get.find<OtherTypeKeyChangeDateLogic>().state;
|
final state = Get.find<OtherTypeKeyChangeDateLogic>().state;
|
||||||
|
|
||||||
@ -27,7 +30,8 @@ class _OtherTypeKeyChangeDatePageState extends State<OtherTypeKeyChangeDatePage>
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.mainBackgroundColor,
|
backgroundColor: AppColors.mainBackgroundColor,
|
||||||
appBar: TitleAppBar(
|
appBar: TitleAppBar(
|
||||||
barTitle: "${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.periodValidity!.tr}",
|
barTitle:
|
||||||
|
"${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.periodValidity!.tr}",
|
||||||
haveBack: true,
|
haveBack: true,
|
||||||
backgroundColor: AppColors.mainColor,
|
backgroundColor: AppColors.mainColor,
|
||||||
actionsList: [
|
actionsList: [
|
||||||
@ -48,7 +52,6 @@ class _OtherTypeKeyChangeDatePageState extends State<OtherTypeKeyChangeDatePage>
|
|||||||
logic.editFingerprintsData();
|
logic.editFingerprintsData();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -72,12 +75,14 @@ class _OtherTypeKeyChangeDatePageState extends State<OtherTypeKeyChangeDatePage>
|
|||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.beginTimeTimestamp.value = DateTime.parse(
|
state.beginTimeTimestamp.value = DateTime.parse(
|
||||||
'${p.year}-${p.month.toString().padLeft(2,'0')}-${p.day.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}').millisecondsSinceEpoch;
|
'${p.year}-${p.month.toString().padLeft(2, '0')}-${p.day.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}')
|
||||||
state.beginTime.value = "${p.year}.${p.month.toString().padLeft(2,'0')}.${p.day.toString().padLeft(2,'0')} ${p.hour.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}";
|
.millisecondsSinceEpoch;
|
||||||
});
|
state.beginTime.value =
|
||||||
});
|
"${p.year}.${p.month.toString().padLeft(2, '0')}.${p.day.toString().padLeft(2, '0')} ${p.hour.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}";
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
||||||
@ -86,12 +91,14 @@ class _OtherTypeKeyChangeDatePageState extends State<OtherTypeKeyChangeDatePage>
|
|||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.endTimeTimestamp.value = DateTime.parse(
|
state.endTimeTimestamp.value = DateTime.parse(
|
||||||
'${p.year}-${p.month.toString().padLeft(2,'0')}-${p.day.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}').millisecondsSinceEpoch;
|
'${p.year}-${p.month.toString().padLeft(2, '0')}-${p.day.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}')
|
||||||
state.endTime.value = "${p.year}.${p.month.toString().padLeft(2,'0')}.${p.day.toString().padLeft(2,'0')} ${p.hour.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}";
|
.millisecondsSinceEpoch;
|
||||||
});
|
state.endTime.value =
|
||||||
});
|
"${p.year}.${p.month.toString().padLeft(2, '0')}.${p.day.toString().padLeft(2, '0')} ${p.hour.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}";
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
import '../../../../tools/commonItem.dart';
|
import '../../../../tools/commonItem.dart';
|
||||||
@ -16,10 +17,12 @@ class OtherTypeKeyChangeValidityDatePage extends StatefulWidget {
|
|||||||
const OtherTypeKeyChangeValidityDatePage({Key? key}) : super(key: key);
|
const OtherTypeKeyChangeValidityDatePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<OtherTypeKeyChangeValidityDatePage> createState() => _OtherTypeKeyChangeValidityDatePageState();
|
State<OtherTypeKeyChangeValidityDatePage> createState() =>
|
||||||
|
_OtherTypeKeyChangeValidityDatePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _OtherTypeKeyChangeValidityDatePageState extends State<OtherTypeKeyChangeValidityDatePage> {
|
class _OtherTypeKeyChangeValidityDatePageState
|
||||||
|
extends State<OtherTypeKeyChangeValidityDatePage> {
|
||||||
final logic = Get.put(OtherTypeKeyChangeValidityDateLogic());
|
final logic = Get.put(OtherTypeKeyChangeValidityDateLogic());
|
||||||
final state = Get.find<OtherTypeKeyChangeValidityDateLogic>().state;
|
final state = Get.find<OtherTypeKeyChangeValidityDateLogic>().state;
|
||||||
|
|
||||||
@ -45,9 +48,9 @@ class _OtherTypeKeyChangeValidityDatePageState extends State<OtherTypeKeyChangeV
|
|||||||
child: SubmitBtn(
|
child: SubmitBtn(
|
||||||
btnName: TranslationLoader.lanKeys!.save!.tr,
|
btnName: TranslationLoader.lanKeys!.save!.tr,
|
||||||
onClick: () {
|
onClick: () {
|
||||||
if(state.pushType.value == 0){
|
if (state.pushType.value == 0) {
|
||||||
logic.editICCardData();
|
logic.editICCardData();
|
||||||
}else if(state.pushType.value == 1){
|
} else if (state.pushType.value == 1) {
|
||||||
logic.editFingerprintsData();
|
logic.editFingerprintsData();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@ -68,7 +71,9 @@ class _OtherTypeKeyChangeValidityDatePageState extends State<OtherTypeKeyChangeV
|
|||||||
height: 60.h,
|
height: 60.h,
|
||||||
// color: Colors.red,
|
// color: Colors.red,
|
||||||
padding: EdgeInsets.only(left: 30.w, top: 15.h),
|
padding: EdgeInsets.only(left: 30.w, top: 15.h),
|
||||||
child: Text(TranslationLoader.lanKeys!.effectiveDay!.tr, style: TextStyle(fontSize: 24.sp, fontWeight: FontWeight.w600))),
|
child: Text(TranslationLoader.lanKeys!.effectiveDay!.tr,
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 24.sp, fontWeight: FontWeight.w600))),
|
||||||
Container(
|
Container(
|
||||||
height: 100.h,
|
height: 100.h,
|
||||||
padding: EdgeInsets.only(left: 10.w, right: 10.w, bottom: 10.h),
|
padding: EdgeInsets.only(left: 10.w, right: 10.w, bottom: 10.h),
|
||||||
@ -117,29 +122,35 @@ class _OtherTypeKeyChangeValidityDatePageState extends State<OtherTypeKeyChangeV
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
if(state.weekDay.value.contains(index)){
|
if (state.weekDay.value.contains(index)) {
|
||||||
state.weekDay.value.remove(index);
|
state.weekDay.value.remove(index);
|
||||||
}else{
|
} else {
|
||||||
state.weekDay.value.add(index);
|
state.weekDay.value.add(index);
|
||||||
}
|
}
|
||||||
state.weekDay.value.sort();
|
state.weekDay.value.sort();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Obx(() => Container(
|
child: Obx(() => Container(
|
||||||
width: 40.w,
|
width: 40.w,
|
||||||
height: 40.w,
|
height: 40.w,
|
||||||
margin: EdgeInsets.all(10.w),
|
margin: EdgeInsets.all(10.w),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: state.weekDay.value.contains(index) ? AppColors.mainColor :Colors.white,
|
color: state.weekDay.value.contains(index)
|
||||||
border: Border.all(width: 1, color: AppColors.btnDisableColor),
|
? AppColors.mainColor
|
||||||
borderRadius: BorderRadius.circular(30.w),
|
: Colors.white,
|
||||||
),
|
border: Border.all(width: 1, color: AppColors.btnDisableColor),
|
||||||
child: Center(
|
borderRadius: BorderRadius.circular(30.w),
|
||||||
child: Text(
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
dateStr,
|
dateStr,
|
||||||
style: TextStyle(fontSize: 20.sp, color: state.weekDay.value.contains(index) ? Colors.white : AppColors.darkGrayTextColor),
|
style: TextStyle(
|
||||||
|
fontSize: 20.sp,
|
||||||
|
color: state.weekDay.value.contains(index)
|
||||||
|
? Colors.white
|
||||||
|
: AppColors.darkGrayTextColor),
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,34 +163,38 @@ class _OtherTypeKeyChangeValidityDatePageState extends State<OtherTypeKeyChangeV
|
|||||||
children: [
|
children: [
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel:
|
leftTitel:
|
||||||
"${TranslationLoader.lanKeys!.begin!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
"${TranslationLoader.lanKeys!.begin!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
||||||
rightTitle: state.beginTime.value,
|
rightTitle: state.beginTime.value,
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
isHaveLine: true,
|
isHaveLine: true,
|
||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.beginTimeTimestamp.value = DateTime.parse(
|
state.beginTimeTimestamp.value = DateTime.parse(
|
||||||
'${p.year}-${p.month.toString().padLeft(2,'0')}-${p.day.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}').millisecondsSinceEpoch;
|
'${p.year}-${p.month.toString().padLeft(2, '0')}-${p.day.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}')
|
||||||
state.beginTime.value = "${p.year}.${p.month.toString().padLeft(2,'0')}.${p.day.toString().padLeft(2,'0')} ${p.hour.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}";
|
.millisecondsSinceEpoch;
|
||||||
});
|
state.beginTime.value =
|
||||||
});
|
"${p.year}.${p.month.toString().padLeft(2, '0')}.${p.day.toString().padLeft(2, '0')} ${p.hour.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}";
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel:
|
leftTitel:
|
||||||
"${TranslationLoader.lanKeys!.end!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
"${TranslationLoader.lanKeys!.end!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
||||||
rightTitle: state.endTime.value,
|
rightTitle: state.endTime.value,
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.endTimeTimestamp.value = DateTime.parse(
|
state.endTimeTimestamp.value = DateTime.parse(
|
||||||
'${p.year}-${p.month.toString().padLeft(2,'0')}-${p.day.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}').millisecondsSinceEpoch;
|
'${p.year}-${p.month.toString().padLeft(2, '0')}-${p.day.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}')
|
||||||
state.endTime.value = "${p.year}.${p.month.toString().padLeft(2,'0')}.${p.day.toString().padLeft(2,'0')} ${p.hour.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}";
|
.millisecondsSinceEpoch;
|
||||||
});
|
state.endTime.value =
|
||||||
});
|
"${p.year}.${p.month.toString().padLeft(2, '0')}.${p.day.toString().padLeft(2, '0')} ${p.hour.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}";
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Container(height: 10.h),
|
Container(height: 10.h),
|
||||||
],
|
],
|
||||||
@ -188,5 +203,4 @@ class _OtherTypeKeyChangeValidityDatePageState extends State<OtherTypeKeyChangeV
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/style/default_style.dart';
|
// import 'package:flutter_pickers/style/default_style.dart';
|
||||||
import 'package:flutter_pickers/style/picker_style.dart';
|
// import 'package:flutter_pickers/style/picker_style.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/pduration.dart';
|
// import 'package:flutter_pickers/time_picker/model/pduration.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/suffix.dart';
|
// import 'package:flutter_pickers/time_picker/model/suffix.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/tools/noData.dart';
|
import 'package:star_lock/tools/noData.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/picker_style.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/pduration.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/suffix.dart';
|
||||||
|
|
||||||
import '../../../../../appRouters.dart';
|
import '../../../../../appRouters.dart';
|
||||||
import '../../../../../app_settings/app_colors.dart';
|
import '../../../../../app_settings/app_colors.dart';
|
||||||
@ -41,10 +46,10 @@ class _CheckingInSetHolidaysPageState extends State<CheckingInSetHolidaysPage> {
|
|||||||
actionsList: [
|
actionsList: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
var data = await Get.toNamed(Routers.checkingInAddHolidaysPage, arguments: {
|
var data = await Get.toNamed(
|
||||||
"companyId": state.companyId.value
|
Routers.checkingInAddHolidaysPage,
|
||||||
});
|
arguments: {"companyId": state.companyId.value});
|
||||||
if(data != null) {
|
if (data != null) {
|
||||||
logic.editStaffLoadData();
|
logic.editStaffLoadData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -59,47 +64,60 @@ class _CheckingInSetHolidaysPageState extends State<CheckingInSetHolidaysPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: Obx(() {
|
body: Obx(() {
|
||||||
return state.holidaysListData.value!.isNotEmpty ? ListView.builder(
|
return state.holidaysListData.value!.isNotEmpty
|
||||||
itemCount: state.holidaysListData.value!.length,
|
? ListView.builder(
|
||||||
itemBuilder: (c, index) {
|
itemCount: state.holidaysListData.value!.length,
|
||||||
HolidaysMonthListData holidaysMonthListData = state.holidaysListData.value![index];
|
itemBuilder: (c, index) {
|
||||||
return _checkingInListMouthItem(holidaysMonthListData);
|
HolidaysMonthListData holidaysMonthListData =
|
||||||
}):const NoData();
|
state.holidaysListData.value![index];
|
||||||
})
|
return _checkingInListMouthItem(holidaysMonthListData);
|
||||||
);
|
})
|
||||||
|
: const NoData();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _checkingInListMouthItem(HolidaysMonthListData holidaysMonthListData) {
|
Widget _checkingInListMouthItem(HolidaysMonthListData holidaysMonthListData) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 140.h*holidaysMonthListData.listItem!.length + 20.w,
|
height: 140.h * holidaysMonthListData.listItem!.length + 20.w,
|
||||||
padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w),
|
padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
color: colorWithMonth(int.parse(holidaysMonthListData.listItem![0].month.toString())),
|
color: colorWithMonth(int.parse(
|
||||||
|
holidaysMonthListData.listItem![0].month.toString())),
|
||||||
width: 100.w,
|
width: 100.w,
|
||||||
height: 140.h*holidaysMonthListData.listItem!.length,
|
height: 140.h * holidaysMonthListData.listItem!.length,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
"${holidaysMonthListData.listItem![0].month}\n${TranslationLoader.lanKeys!.month!.tr}",
|
"${holidaysMonthListData.listItem![0].month}\n${TranslationLoader.lanKeys!.month!.tr}",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 28.sp, color: Colors.white),
|
style: TextStyle(fontSize: 28.sp, color: Colors.white),
|
||||||
))),
|
))),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 140.h*holidaysMonthListData.listItem!.length,
|
height: 140.h * holidaysMonthListData.listItem!.length,
|
||||||
width: 1.sw - 100.w - 20.w*2,
|
width: 1.sw - 100.w - 20.w * 2,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
itemCount: holidaysMonthListData.listItem!.length,
|
itemCount: holidaysMonthListData.listItem!.length,
|
||||||
itemBuilder: (c, index) {
|
itemBuilder: (c, index) {
|
||||||
ListItem listItem = holidaysMonthListData.listItem![index];
|
ListItem listItem = holidaysMonthListData.listItem![index];
|
||||||
return _checkingInListItem(index, listItem.vacationName, DateTool().dateToYMDString(listItem.vacationStartDate.toString()), DateTool().dateToYMDString(listItem.vacationEndDate.toString()), listItem.fillClassDate!.isNotEmpty ? DateTool().dateToYMDString(listItem.fillClassDate.toString()):"", () async {
|
return _checkingInListItem(
|
||||||
var data = await Get.toNamed(Routers.checkingInDeletHolidaysPage, arguments: {
|
index,
|
||||||
"listItem": listItem
|
listItem.vacationName,
|
||||||
});
|
DateTool().dateToYMDString(
|
||||||
if(data != null) {
|
listItem.vacationStartDate.toString()),
|
||||||
|
DateTool().dateToYMDString(
|
||||||
|
listItem.vacationEndDate.toString()),
|
||||||
|
listItem.fillClassDate!.isNotEmpty
|
||||||
|
? DateTool().dateToYMDString(
|
||||||
|
listItem.fillClassDate.toString())
|
||||||
|
: "", () async {
|
||||||
|
var data = await Get.toNamed(
|
||||||
|
Routers.checkingInDeletHolidaysPage,
|
||||||
|
arguments: {"listItem": listItem});
|
||||||
|
if (data != null) {
|
||||||
logic.editStaffLoadData();
|
logic.editStaffLoadData();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -111,13 +129,19 @@ class _CheckingInSetHolidaysPageState extends State<CheckingInSetHolidaysPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _checkingInListItem(int index, String? lockTypeTitle, String? vacationStartDate, String? vacationEndDate, String? makeUpClass, Function() action) {
|
Widget _checkingInListItem(
|
||||||
|
int index,
|
||||||
|
String? lockTypeTitle,
|
||||||
|
String? vacationStartDate,
|
||||||
|
String? vacationEndDate,
|
||||||
|
String? makeUpClass,
|
||||||
|
Function() action) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: action,
|
onTap: action,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
color:Colors.white,
|
color: Colors.white,
|
||||||
height: 140.h,
|
height: 140.h,
|
||||||
padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 10.h),
|
padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 10.h),
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -174,27 +198,27 @@ class _CheckingInSetHolidaysPageState extends State<CheckingInSetHolidaysPage> {
|
|||||||
showListType();
|
showListType();
|
||||||
},
|
},
|
||||||
child: Obx(() => Container(
|
child: Obx(() => Container(
|
||||||
width: 300.w,
|
width: 300.w,
|
||||||
height: 50.h,
|
height: 50.h,
|
||||||
color: AppColors.mainColor,
|
color: AppColors.mainColor,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"${state.seletYear.value}${TranslationLoader.lanKeys!.year!.tr}",
|
"${state.seletYear.value}${TranslationLoader.lanKeys!.year!.tr}",
|
||||||
style: TextStyle(color: Colors.white, fontSize: 26.sp),
|
style: TextStyle(color: Colors.white, fontSize: 26.sp),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 5.w,
|
||||||
|
),
|
||||||
|
Image.asset(
|
||||||
|
'images/main/icon_lockDetail_checkIn_topTitle.png',
|
||||||
|
width: 22.w,
|
||||||
|
height: 16.w,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
SizedBox(
|
)),
|
||||||
width: 5.w,
|
|
||||||
),
|
|
||||||
Image.asset(
|
|
||||||
'images/main/icon_lockDetail_checkIn_topTitle.png',
|
|
||||||
width: 22.w,
|
|
||||||
height: 16.w,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,9 +266,9 @@ class _CheckingInSetHolidaysPageState extends State<CheckingInSetHolidaysPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color colorWithMonth(int month){
|
Color colorWithMonth(int month) {
|
||||||
Color colorType;
|
Color colorType;
|
||||||
switch (month){
|
switch (month) {
|
||||||
case 1:
|
case 1:
|
||||||
colorType = const Color(0xFFb8d152);
|
colorType = const Color(0xFFb8d152);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
@ -16,7 +18,8 @@ class CheckingInSetWorkTimePage extends StatefulWidget {
|
|||||||
const CheckingInSetWorkTimePage({Key? key}) : super(key: key);
|
const CheckingInSetWorkTimePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<CheckingInSetWorkTimePage> createState() => _CheckingInSetWorkTimePageState();
|
State<CheckingInSetWorkTimePage> createState() =>
|
||||||
|
_CheckingInSetWorkTimePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CheckingInSetWorkTimePageState extends State<CheckingInSetWorkTimePage> {
|
class _CheckingInSetWorkTimePageState extends State<CheckingInSetWorkTimePage> {
|
||||||
@ -27,77 +30,100 @@ class _CheckingInSetWorkTimePageState extends State<CheckingInSetWorkTimePage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.mainBackgroundColor,
|
backgroundColor: AppColors.mainBackgroundColor,
|
||||||
appBar: TitleAppBar(barTitle: "${TranslationLoader.lanKeys!.work!.tr} ${TranslationLoader.lanKeys!.time!.tr} ${TranslationLoader.lanKeys!.set!.tr}", haveBack:true, backgroundColor: AppColors.mainColor),
|
appBar: TitleAppBar(
|
||||||
|
barTitle:
|
||||||
|
"${TranslationLoader.lanKeys!.work!.tr} ${TranslationLoader.lanKeys!.time!.tr} ${TranslationLoader.lanKeys!.set!.tr}",
|
||||||
|
haveBack: true,
|
||||||
|
backgroundColor: AppColors.mainColor),
|
||||||
body: buildMainUI(),
|
body: buildMainUI(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildMainUI(){
|
Widget buildMainUI() {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Obx(() => CommonItem(leftTitel:TranslationLoader.lanKeys!.officeHours!.tr, rightTitle:state.beginTime.value, isHaveDirection: true, isHaveLine: true, action:(){
|
Obx(() => CommonItem(
|
||||||
Pickers.showDatePicker(context, mode: DateMode.HM,
|
leftTitel: TranslationLoader.lanKeys!.officeHours!.tr,
|
||||||
onConfirm: (p) {
|
rightTitle: state.beginTime.value,
|
||||||
|
isHaveDirection: true,
|
||||||
|
isHaveLine: true,
|
||||||
|
action: () {
|
||||||
|
Pickers.showDatePicker(context, mode: DateMode.HM,
|
||||||
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
DateTime today = DateTime.now();
|
DateTime today = DateTime.now();
|
||||||
state.beginTimeTimestamp.value = DateTime.parse(
|
state.beginTimeTimestamp.value = DateTime.parse(
|
||||||
'${today.year}-${today.month.toString().padLeft(2,'0')}-${today.day.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}').millisecondsSinceEpoch.toString();
|
'${today.year}-${today.month.toString().padLeft(2, '0')}-${today.day.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}')
|
||||||
state.beginTime.value = "${p.hour.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}";
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
|
state.beginTime.value =
|
||||||
|
"${p.hour.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})),
|
})),
|
||||||
Obx(() => CommonItem(leftTitel:TranslationLoader.lanKeys!.closingTime!.tr, rightTitle:state.endTime.value, isHaveDirection: true, action:(){
|
Obx(() => CommonItem(
|
||||||
Pickers.showDatePicker(context, mode: DateMode.HM,
|
leftTitel: TranslationLoader.lanKeys!.closingTime!.tr,
|
||||||
onConfirm: (p) {
|
rightTitle: state.endTime.value,
|
||||||
|
isHaveDirection: true,
|
||||||
|
action: () {
|
||||||
|
Pickers.showDatePicker(context, mode: DateMode.HM,
|
||||||
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
DateTime today = DateTime.now();
|
DateTime today = DateTime.now();
|
||||||
state.endTimeTimestamp.value = DateTime.parse(
|
state.endTimeTimestamp.value = DateTime.parse(
|
||||||
'${today.year}-${today.month.toString().padLeft(2,'0')}-${today.day.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}').millisecondsSinceEpoch.toString();
|
'${today.year}-${today.month.toString().padLeft(2, '0')}-${today.day.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}')
|
||||||
state.endTime.value = "${p.hour.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}";
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
|
state.endTime.value =
|
||||||
|
"${p.hour.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})),
|
})),
|
||||||
SizedBox(height: 30.h,),
|
SizedBox(
|
||||||
SubmitBtn(btnName: TranslationLoader.lanKeys!.sure!.tr,
|
height: 30.h,
|
||||||
|
),
|
||||||
|
SubmitBtn(
|
||||||
|
btnName: TranslationLoader.lanKeys!.sure!.tr,
|
||||||
borderRadius: 20.w,
|
borderRadius: 20.w,
|
||||||
fontSize: 32.sp,
|
fontSize: 32.sp,
|
||||||
margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 20.w),
|
margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 20.w),
|
||||||
padding: EdgeInsets.only(top: 20.w, bottom: 20.w),
|
padding: EdgeInsets.only(top: 20.w, bottom: 20.w),
|
||||||
onClick: () {
|
onClick: () {
|
||||||
if(state.beginTimeTimestamp.value.isEmpty){
|
if (state.beginTimeTimestamp.value.isEmpty) {
|
||||||
Toast.show(msg: "请选择开始时间");
|
Toast.show(msg: "请选择开始时间");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.endTimeTimestamp.value.isEmpty){
|
if (state.endTimeTimestamp.value.isEmpty) {
|
||||||
Toast.show(msg: "请选择结束时间");
|
Toast.show(msg: "请选择结束时间");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(int.parse(state.beginTimeTimestamp.value) > int.parse(state.endTimeTimestamp.value)){
|
if (int.parse(state.beginTimeTimestamp.value) >
|
||||||
|
int.parse(state.endTimeTimestamp.value)) {
|
||||||
Toast.show(msg: "结束时间不能大于开始时间");
|
Toast.show(msg: "结束时间不能大于开始时间");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(state.pushType.value == "2"){
|
if (state.pushType.value == "2") {
|
||||||
logic.editCheckInSetInfoData();
|
logic.editCheckInSetInfoData();
|
||||||
}else{
|
} else {
|
||||||
Get.back(result: {
|
Get.back(result: {
|
||||||
"beginTime":state.beginTime.value,
|
"beginTime": state.beginTime.value,
|
||||||
"beginTimeTimestamp":state.beginTimeTimestamp.value,
|
"beginTimeTimestamp": state.beginTimeTimestamp.value,
|
||||||
"endTime":state.endTime.value,
|
"endTime": state.endTime.value,
|
||||||
"endTimeTimestamp":state.endTimeTimestamp.value,
|
"endTimeTimestamp": state.endTimeTimestamp.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getNowDate(){
|
String getNowDate() {
|
||||||
// 获取当前时间对象
|
// 获取当前时间对象
|
||||||
DateTime today = DateTime.now();
|
DateTime today = DateTime.now();
|
||||||
String dateSlug ="${today.hour.toString().padLeft(2,'0')}:${today.minute.toString().padLeft(2,'0')}";
|
String dateSlug =
|
||||||
|
"${today.hour.toString().padLeft(2, '0')}:${today.minute.toString().padLeft(2, '0')}";
|
||||||
|
|
||||||
// //获取当前时间的年
|
// //获取当前时间的年
|
||||||
// int year = now.year;
|
// int year = now.year;
|
||||||
@ -115,5 +141,4 @@ class _CheckingInSetWorkTimePageState extends State<CheckingInSetWorkTimePage> {
|
|||||||
// print("组合 $year-$month-$day $hour:$minute:$millisecond");
|
// print("组合 $year-$month-$day $hour:$minute:$millisecond");
|
||||||
return dateSlug;
|
return dateSlug;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart';
|
||||||
@ -8,6 +8,8 @@ import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity
|
|||||||
import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKeyEntity.dart';
|
import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKeyEntity.dart';
|
||||||
import 'package:star_lock/network/api_repository.dart';
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
import '../../../../../app_settings/app_colors.dart';
|
import '../../../../../app_settings/app_colors.dart';
|
||||||
@ -36,7 +38,7 @@ class _ElectronicKeyDetailChangeDateState
|
|||||||
late List weekDays = [];
|
late List weekDays = [];
|
||||||
late String pwdId = '';
|
late String pwdId = '';
|
||||||
late String lockId = '';
|
late String lockId = '';
|
||||||
late String fromType = '';// 1 从指纹详情进入
|
late String fromType = ''; // 1 从指纹详情进入
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -67,9 +69,8 @@ class _ElectronicKeyDetailChangeDateState
|
|||||||
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if(fromType == "1"){
|
if (fromType == "1") {
|
||||||
|
} else {
|
||||||
}else{
|
|
||||||
if (lockId.isNotEmpty && pwdId.isNotEmpty) {
|
if (lockId.isNotEmpty && pwdId.isNotEmpty) {
|
||||||
updatePwdRequest();
|
updatePwdRequest();
|
||||||
} else {
|
} else {
|
||||||
@ -158,7 +159,6 @@ class _ElectronicKeyDetailChangeDateState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String intToStr(int v) {
|
String intToStr(int v) {
|
||||||
return (v < 10) ? "0$v" : "$v";
|
return (v < 10) ? "0$v" : "$v";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
import 'package:date_format/date_format.dart';
|
import 'package:date_format/date_format.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyPeriodValidity/KeyPeriodValidityModel.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyPeriodValidity/KeyPeriodValidityModel.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_logic.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyPeriodValidity/electronicKeyPeriodValidity_logic.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
||||||
@ -9,6 +9,8 @@ import 'package:star_lock/app_settings/app_colors.dart';
|
|||||||
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserListEntity.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserListEntity.dart';
|
||||||
import 'package:star_lock/network/api_repository.dart';
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
import '../../../../../tools/commonItem.dart';
|
import '../../../../../tools/commonItem.dart';
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/app_settings/app_colors.dart';
|
import 'package:star_lock/app_settings/app_colors.dart';
|
||||||
@ -10,6 +10,8 @@ import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart
|
|||||||
import 'package:star_lock/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_logic.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_logic.dart';
|
||||||
import 'package:star_lock/network/api_repository.dart';
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/storage.dart';
|
import 'package:star_lock/tools/storage.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
import '../../../../appRouters.dart';
|
import '../../../../appRouters.dart';
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
@ -31,7 +31,6 @@ class _AddFaceTypePageState extends State<AddFaceTypePage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
return indexChangeWidget();
|
return indexChangeWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,8 +42,10 @@ class _AddFaceTypePageState extends State<AddFaceTypePage> {
|
|||||||
// return sendElectronicKeySucceed();
|
// return sendElectronicKeySucceed();
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -54,8 +55,10 @@ class _AddFaceTypePageState extends State<AddFaceTypePage> {
|
|||||||
// 限时
|
// 限时
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
keyTimeLimitWidget(),
|
keyTimeLimitWidget(),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
@ -67,18 +70,24 @@ class _AddFaceTypePageState extends State<AddFaceTypePage> {
|
|||||||
// 循环
|
// 循环
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
CommonItem(
|
CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr,
|
leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr,
|
||||||
rightTitle: "",
|
rightTitle: "",
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
action: () async {
|
action: () async {
|
||||||
Map result = await Get.toNamed(Routers.electronicKeyPeriodValidityPage);
|
Map result = await Get.toNamed(
|
||||||
|
Routers.electronicKeyPeriodValidityPage);
|
||||||
state.weekdaysList.value = result['validityValue'];
|
state.weekdaysList.value = result['validityValue'];
|
||||||
state.effectiveDateTime.value = result['starDate'].millisecondsSinceEpoch;
|
state.effectiveDateTime.value =
|
||||||
state.failureDateTime.value = result['endDate'].millisecondsSinceEpoch;
|
result['starDate'].millisecondsSinceEpoch;
|
||||||
print('得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}');
|
state.failureDateTime.value =
|
||||||
|
result['endDate'].millisecondsSinceEpoch;
|
||||||
|
print(
|
||||||
|
'得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}');
|
||||||
}),
|
}),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
@ -118,13 +127,17 @@ class _AddFaceTypePageState extends State<AddFaceTypePage> {
|
|||||||
action: () async {
|
action: () async {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.beginTime.value = '${p.year}-${p.month!.toString().padLeft(2,'0')}-${p.day!.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}';
|
state.beginTime.value =
|
||||||
state.beginTimeTimestamp.value = DateTime.parse(state.beginTime.value).millisecondsSinceEpoch.toString();
|
'${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}';
|
||||||
});
|
state.beginTimeTimestamp.value =
|
||||||
});
|
DateTime.parse(state.beginTime.value)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
||||||
@ -133,13 +146,17 @@ class _AddFaceTypePageState extends State<AddFaceTypePage> {
|
|||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.endTime.value = '${p.year}-${p.month!.toString().padLeft(2,'0')}-${p.day!.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}';
|
state.endTime.value =
|
||||||
state.endTimeTimestamp.value = DateTime.parse(state.endTime.value).millisecondsSinceEpoch.toString();
|
'${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}';
|
||||||
});
|
state.endTimeTimestamp.value =
|
||||||
});
|
DateTime.parse(state.endTime.value)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Container(height: 10.h),
|
Container(height: 10.h),
|
||||||
],
|
],
|
||||||
@ -157,23 +174,23 @@ class _AddFaceTypePageState extends State<AddFaceTypePage> {
|
|||||||
// rightWidget: SizedBox(
|
// rightWidget: SizedBox(
|
||||||
// width: 60.w, height: 50.h, child: _isStressFingerprint())),
|
// width: 60.w, height: 50.h, child: _isStressFingerprint())),
|
||||||
SizedBox(height: 30.h),
|
SizedBox(height: 30.h),
|
||||||
SubmitBtn(btnName: TranslationLoader.lanKeys!.next!.tr, onClick: () async {
|
SubmitBtn(
|
||||||
|
btnName: TranslationLoader.lanKeys!.next!.tr,
|
||||||
|
onClick: () async {
|
||||||
|
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
||||||
|
if (isDemoMode == false) {
|
||||||
|
// print("state.seletType:${state.seletType.value}");
|
||||||
|
if (state.nameController.text.isEmpty) {
|
||||||
|
Toast.show(msg: "请输入姓名");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
Get.toNamed(Routers.addFaceTipPage);
|
||||||
if(isDemoMode == false){
|
} else {
|
||||||
// print("state.seletType:${state.seletType.value}");
|
// Get.toNamed(Routers.seletLockTypePage);
|
||||||
if(state.nameController.text.isEmpty){
|
Toast.show(msg: "演示模式");
|
||||||
Toast.show(msg: "请输入姓名");
|
}
|
||||||
return;
|
}),
|
||||||
}
|
|
||||||
|
|
||||||
Get.toNamed(Routers.addFaceTipPage);
|
|
||||||
}else{
|
|
||||||
// Get.toNamed(Routers.seletLockTypePage);
|
|
||||||
Toast.show(msg: "演示模式");
|
|
||||||
}
|
|
||||||
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -294,5 +311,4 @@ class _AddFaceTypePageState extends State<AddFaceTypePage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
import '../../../../appRouters.dart';
|
import '../../../../appRouters.dart';
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
@ -16,12 +17,18 @@ import '../../../../translations/trans_lib.dart';
|
|||||||
import 'addFingerprintType_logic.dart';
|
import 'addFingerprintType_logic.dart';
|
||||||
|
|
||||||
class AddFingerprintTypePage extends StatefulWidget {
|
class AddFingerprintTypePage extends StatefulWidget {
|
||||||
final String seletType;// 永久限时循环下标
|
final String seletType; // 永久限时循环下标
|
||||||
final int lockId;
|
final int lockId;
|
||||||
final int fromType;// // 1从添加钥匙列表进入 2从考勤添加员工入口进入
|
final int fromType; // // 1从添加钥匙列表进入 2从考勤添加员工入口进入
|
||||||
final String fromTypeTwoStaffName;// 从添加员工进入 传入员工名字
|
final String fromTypeTwoStaffName; // 从添加员工进入 传入员工名字
|
||||||
|
|
||||||
const AddFingerprintTypePage({Key? key, required this.seletType, required this.lockId, required this.fromType, required this.fromTypeTwoStaffName}) : super(key: key);
|
const AddFingerprintTypePage(
|
||||||
|
{Key? key,
|
||||||
|
required this.seletType,
|
||||||
|
required this.lockId,
|
||||||
|
required this.fromType,
|
||||||
|
required this.fromTypeTwoStaffName})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AddFingerprintTypePage> createState() => _AddFingerprintTypePageState();
|
State<AddFingerprintTypePage> createState() => _AddFingerprintTypePageState();
|
||||||
@ -51,7 +58,10 @@ class _AddFingerprintTypePageState extends State<AddFingerprintTypePage> {
|
|||||||
// return sendElectronicKeySucceed();
|
// return sendElectronicKeySucceed();
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr, TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
perpetualKeyWidget(
|
||||||
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -61,7 +71,10 @@ class _AddFingerprintTypePageState extends State<AddFingerprintTypePage> {
|
|||||||
// 限时
|
// 限时
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr, TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
perpetualKeyWidget(
|
||||||
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
keyTimeLimitWidget(),
|
keyTimeLimitWidget(),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
@ -73,18 +86,24 @@ class _AddFingerprintTypePageState extends State<AddFingerprintTypePage> {
|
|||||||
// 循环
|
// 循环
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
CommonItem(
|
CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr,
|
leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr,
|
||||||
rightTitle: "",
|
rightTitle: "",
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
action: () async {
|
action: () async {
|
||||||
Map result = await Get.toNamed(Routers.electronicKeyPeriodValidityPage);
|
Map result = await Get.toNamed(
|
||||||
|
Routers.electronicKeyPeriodValidityPage);
|
||||||
state.weekdaysList.value = result['validityValue'];
|
state.weekdaysList.value = result['validityValue'];
|
||||||
state.effectiveDateTime.value = result['starDate'].millisecondsSinceEpoch;
|
state.effectiveDateTime.value =
|
||||||
state.failureDateTime.value = result['endDate'].millisecondsSinceEpoch;
|
result['starDate'].millisecondsSinceEpoch;
|
||||||
print('得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}');
|
state.failureDateTime.value =
|
||||||
|
result['endDate'].millisecondsSinceEpoch;
|
||||||
|
print(
|
||||||
|
'得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}');
|
||||||
}),
|
}),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
@ -124,13 +143,17 @@ class _AddFingerprintTypePageState extends State<AddFingerprintTypePage> {
|
|||||||
action: () async {
|
action: () async {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.beginTime.value = '${p.year}-${p.month!.toString().padLeft(2,'0')}-${p.day!.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}';
|
state.beginTime.value =
|
||||||
state.beginTimeTimestamp.value = DateTime.parse(state.beginTime.value).millisecondsSinceEpoch.toString();
|
'${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}';
|
||||||
});
|
state.beginTimeTimestamp.value =
|
||||||
});
|
DateTime.parse(state.beginTime.value)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
||||||
@ -139,13 +162,17 @@ class _AddFingerprintTypePageState extends State<AddFingerprintTypePage> {
|
|||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.endTime.value = '${p.year}-${p.month!.toString().padLeft(2,'0')}-${p.day!.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}';
|
state.endTime.value =
|
||||||
state.endTimeTimestamp.value = DateTime.parse(state.endTime.value).millisecondsSinceEpoch.toString();
|
'${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}';
|
||||||
});
|
state.endTimeTimestamp.value =
|
||||||
});
|
DateTime.parse(state.endTime.value)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Container(height: 10.h),
|
Container(height: 10.h),
|
||||||
],
|
],
|
||||||
@ -163,23 +190,23 @@ class _AddFingerprintTypePageState extends State<AddFingerprintTypePage> {
|
|||||||
rightWidget: SizedBox(
|
rightWidget: SizedBox(
|
||||||
width: 60.w, height: 50.h, child: _isStressFingerprint())),
|
width: 60.w, height: 50.h, child: _isStressFingerprint())),
|
||||||
SizedBox(height: 30.h),
|
SizedBox(height: 30.h),
|
||||||
SubmitBtn(btnName: TranslationLoader.lanKeys!.next!.tr, onClick: () async {
|
SubmitBtn(
|
||||||
|
btnName: TranslationLoader.lanKeys!.next!.tr,
|
||||||
|
onClick: () async {
|
||||||
|
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
||||||
|
if (isDemoMode == false) {
|
||||||
|
// print("state.seletType:${state.seletType.value}");
|
||||||
|
if (state.nameController.text.isEmpty) {
|
||||||
|
Toast.show(msg: "请输入姓名");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
logic.addFingerprintsData();
|
||||||
if(isDemoMode == false){
|
} else {
|
||||||
// print("state.seletType:${state.seletType.value}");
|
// Get.toNamed(Routers.seletLockTypePage);
|
||||||
if(state.nameController.text.isEmpty){
|
Toast.show(msg: "演示模式");
|
||||||
Toast.show(msg: "请输入姓名");
|
}
|
||||||
return;
|
}),
|
||||||
}
|
|
||||||
|
|
||||||
logic.addFingerprintsData();
|
|
||||||
}else{
|
|
||||||
// Get.toNamed(Routers.seletLockTypePage);
|
|
||||||
Toast.show(msg: "演示模式");
|
|
||||||
}
|
|
||||||
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -300,5 +327,4 @@ class _AddFingerprintTypePageState extends State<AddFingerprintTypePage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/style/default_style.dart';
|
// import 'package:flutter_pickers/style/default_style.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/appRouters.dart';
|
import 'package:star_lock/appRouters.dart';
|
||||||
import 'package:star_lock/tools/commonItem.dart';
|
import 'package:star_lock/tools/commonItem.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/default_style.dart';
|
||||||
import 'package:star_lock/tools/submitBtn.dart';
|
import 'package:star_lock/tools/submitBtn.dart';
|
||||||
|
|
||||||
import '../../../../../app_settings/app_colors.dart';
|
import '../../../../../app_settings/app_colors.dart';
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
import '../../../../tools/commonItem.dart';
|
import '../../../../tools/commonItem.dart';
|
||||||
@ -32,89 +34,91 @@ class _NormallyOpenModePageState extends State<NormallyOpenModePage> {
|
|||||||
haveBack: true,
|
haveBack: true,
|
||||||
backgroundColor: AppColors.mainColor),
|
backgroundColor: AppColors.mainColor),
|
||||||
body: Obx(() => ListView(
|
body: Obx(() => ListView(
|
||||||
children: [
|
children: [
|
||||||
CommonItem(
|
CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.normallyOpenMode!.tr,
|
leftTitel: TranslationLoader.lanKeys!.normallyOpenMode!.tr,
|
||||||
rightTitle: "",
|
rightTitle: "",
|
||||||
isHaveLine: false,
|
isHaveLine: false,
|
||||||
isHaveRightWidget: true,
|
isHaveRightWidget: true,
|
||||||
rightWidget:
|
rightWidget: SizedBox(
|
||||||
SizedBox(width: 60.w, height: 50.h, child: _normallyOpenModeSwitch())),
|
width: 60.w,
|
||||||
SizedBox(
|
height: 50.h,
|
||||||
height: 1.h,
|
child: _normallyOpenModeSwitch())),
|
||||||
),
|
SizedBox(
|
||||||
Container(
|
height: 1.h,
|
||||||
padding: EdgeInsets.only(
|
),
|
||||||
left: 30.w, right: 30.w, top: 20.w, bottom: 20.w),
|
Container(
|
||||||
color: Colors.white,
|
padding: EdgeInsets.only(
|
||||||
child: Row(
|
left: 30.w, right: 30.w, top: 20.w, bottom: 20.w),
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
color: Colors.white,
|
||||||
children: [
|
child: Row(
|
||||||
Expanded(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
child: Text(
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
TranslationLoader.lanKeys!.normallyOpenModeTip!.tr,
|
TranslationLoader.lanKeys!.normallyOpenModeTip!.tr,
|
||||||
style: TextStyle(fontSize: 20.sp),
|
style: TextStyle(fontSize: 20.sp),
|
||||||
)),
|
)),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10.h,
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: state.isOpenNormallyOpenMode.value,
|
|
||||||
child: Container(
|
|
||||||
color: Colors.white,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
// CommonItem(
|
|
||||||
// leftTitel: TranslationLoader.lanKeys!.automaticUnLock!.tr,
|
|
||||||
// rightTitle: "",
|
|
||||||
// isHaveLine: false,
|
|
||||||
// isHaveRightWidget: true,
|
|
||||||
// rightWidget:
|
|
||||||
// SizedBox(width: 60.w, height: 50.h, child: _autoUnlockSwitch())),
|
|
||||||
// Container(
|
|
||||||
// height: 1.h,
|
|
||||||
// color: AppColors.mainBackgroundColor,
|
|
||||||
// ),
|
|
||||||
// Container(
|
|
||||||
// padding: EdgeInsets.only(
|
|
||||||
// left: 30.w, right: 30.w, top: 20.w, bottom: 20.w),
|
|
||||||
// color: Colors.white,
|
|
||||||
// child: Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
// children: [
|
|
||||||
// Expanded(
|
|
||||||
// child: Text(
|
|
||||||
// TranslationLoader.lanKeys!.automaticUnLockTip!.tr,
|
|
||||||
// style: TextStyle(fontSize: 20.sp),
|
|
||||||
// )),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// Container(
|
|
||||||
// height: 10.h,
|
|
||||||
// color: AppColors.mainBackgroundColor,
|
|
||||||
// ),
|
|
||||||
topWidget(),
|
|
||||||
SizedBox(
|
|
||||||
height: 10.h,
|
|
||||||
),
|
|
||||||
bottomWidget()
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)),
|
),
|
||||||
Container(
|
SizedBox(
|
||||||
margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 30.h),
|
height: 10.h,
|
||||||
child: SubmitBtn(
|
),
|
||||||
btnName: TranslationLoader.lanKeys!.save!.tr,
|
Visibility(
|
||||||
onClick: () {
|
visible: state.isOpenNormallyOpenMode.value,
|
||||||
logic.sendAutoLock();
|
child: Container(
|
||||||
}),
|
color: Colors.white,
|
||||||
),
|
child: Column(
|
||||||
],
|
children: [
|
||||||
)));
|
// CommonItem(
|
||||||
|
// leftTitel: TranslationLoader.lanKeys!.automaticUnLock!.tr,
|
||||||
|
// rightTitle: "",
|
||||||
|
// isHaveLine: false,
|
||||||
|
// isHaveRightWidget: true,
|
||||||
|
// rightWidget:
|
||||||
|
// SizedBox(width: 60.w, height: 50.h, child: _autoUnlockSwitch())),
|
||||||
|
// Container(
|
||||||
|
// height: 1.h,
|
||||||
|
// color: AppColors.mainBackgroundColor,
|
||||||
|
// ),
|
||||||
|
// Container(
|
||||||
|
// padding: EdgeInsets.only(
|
||||||
|
// left: 30.w, right: 30.w, top: 20.w, bottom: 20.w),
|
||||||
|
// color: Colors.white,
|
||||||
|
// child: Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// Expanded(
|
||||||
|
// child: Text(
|
||||||
|
// TranslationLoader.lanKeys!.automaticUnLockTip!.tr,
|
||||||
|
// style: TextStyle(fontSize: 20.sp),
|
||||||
|
// )),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Container(
|
||||||
|
// height: 10.h,
|
||||||
|
// color: AppColors.mainBackgroundColor,
|
||||||
|
// ),
|
||||||
|
topWidget(),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
bottomWidget()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 30.h),
|
||||||
|
child: SubmitBtn(
|
||||||
|
btnName: TranslationLoader.lanKeys!.save!.tr,
|
||||||
|
onClick: () {
|
||||||
|
logic.sendAutoLock();
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget topWidget() {
|
Widget topWidget() {
|
||||||
@ -180,9 +184,9 @@ class _NormallyOpenModePageState extends State<NormallyOpenModePage> {
|
|||||||
}
|
}
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if(state.weekDays.value.contains(index)){
|
if (state.weekDays.value.contains(index)) {
|
||||||
state.weekDays.value.remove(index);
|
state.weekDays.value.remove(index);
|
||||||
}else{
|
} else {
|
||||||
state.weekDays.value.add(index);
|
state.weekDays.value.add(index);
|
||||||
}
|
}
|
||||||
state.weekDays.value.sort();
|
state.weekDays.value.sort();
|
||||||
@ -190,20 +194,26 @@ class _NormallyOpenModePageState extends State<NormallyOpenModePage> {
|
|||||||
// print("index:$index data:${state.normallyOpenPeriod.value}");
|
// print("index:$index data:${state.normallyOpenPeriod.value}");
|
||||||
},
|
},
|
||||||
child: Obx(() => Container(
|
child: Obx(() => Container(
|
||||||
width: 40.w,
|
width: 40.w,
|
||||||
height: 40.w,
|
height: 40.w,
|
||||||
margin: EdgeInsets.all(10.w),
|
margin: EdgeInsets.all(10.w),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: state.weekDays.value.contains(index) ? AppColors.mainColor :Colors.white,
|
color: state.weekDays.value.contains(index)
|
||||||
border: Border.all(width: 1, color: AppColors.btnDisableColor),
|
? AppColors.mainColor
|
||||||
borderRadius: BorderRadius.circular(30.w),
|
: Colors.white,
|
||||||
),
|
border: Border.all(width: 1, color: AppColors.btnDisableColor),
|
||||||
child: Center(
|
borderRadius: BorderRadius.circular(30.w),
|
||||||
child: Text(
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
dateStr,
|
dateStr,
|
||||||
style: TextStyle(fontSize: 20.sp, color: state.weekDays.value.contains(index) ? Colors.white : AppColors.darkGrayTextColor),
|
style: TextStyle(
|
||||||
|
fontSize: 20.sp,
|
||||||
|
color: state.weekDays.value.contains(index)
|
||||||
|
? Colors.white
|
||||||
|
: AppColors.darkGrayTextColor),
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,16 +226,16 @@ class _NormallyOpenModePageState extends State<NormallyOpenModePage> {
|
|||||||
),
|
),
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel:
|
leftTitel:
|
||||||
"${TranslationLoader.lanKeys!.normallyOpen!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
"${TranslationLoader.lanKeys!.normallyOpen!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
||||||
rightTitle: "",
|
rightTitle: "",
|
||||||
isHaveLine: true,
|
isHaveLine: true,
|
||||||
isHaveRightWidget: true,
|
isHaveRightWidget: true,
|
||||||
rightWidget: GestureDetector(
|
rightWidget: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// 选择全天模式
|
// 选择全天模式
|
||||||
if(state.isAllDay.value == 1){
|
if (state.isAllDay.value == 1) {
|
||||||
state.isAllDay.value = 0;
|
state.isAllDay.value = 0;
|
||||||
}else{
|
} else {
|
||||||
state.isAllDay.value = 1;
|
state.isAllDay.value = 1;
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -240,7 +250,9 @@ class _NormallyOpenModePageState extends State<NormallyOpenModePage> {
|
|||||||
width: 5.w,
|
width: 5.w,
|
||||||
),
|
),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
state.isAllDay.value == 1 ? 'images/icon_round_selet.png': 'images/icon_round_unSelet.png',
|
state.isAllDay.value == 1
|
||||||
|
? 'images/icon_round_selet.png'
|
||||||
|
: 'images/icon_round_unSelet.png',
|
||||||
width: 30.w,
|
width: 30.w,
|
||||||
height: 30.w,
|
height: 30.w,
|
||||||
),
|
),
|
||||||
@ -255,32 +267,34 @@ class _NormallyOpenModePageState extends State<NormallyOpenModePage> {
|
|||||||
children: [
|
children: [
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel:
|
leftTitel:
|
||||||
"${TranslationLoader.lanKeys!.begin!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
"${TranslationLoader.lanKeys!.begin!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
||||||
rightTitle: state.beginTime.value,
|
rightTitle: state.beginTime.value,
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
isHaveLine: true,
|
isHaveLine: true,
|
||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.HM,
|
Pickers.showDatePicker(context, mode: DateMode.HM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.beginTimeMinute.value = p.hour!*60 + p.minute!;
|
state.beginTimeMinute.value =
|
||||||
state.beginTime.value = "${p.hour}:${p.minute!}";
|
p.hour! * 60 + p.minute!;
|
||||||
});
|
state.beginTime.value = "${p.hour}:${p.minute!}";
|
||||||
});
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel:
|
leftTitel:
|
||||||
"${TranslationLoader.lanKeys!.end!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
"${TranslationLoader.lanKeys!.end!.tr}${TranslationLoader.lanKeys!.time!.tr}",
|
||||||
rightTitle: state.endTime.value,
|
rightTitle: state.endTime.value,
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.HM,
|
Pickers.showDatePicker(context, mode: DateMode.HM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.endTimeMinute.value = p.hour!*60 + p.minute!;
|
state.endTimeMinute.value =
|
||||||
state.endTime.value = "${p.hour}:${p.minute!}";
|
p.hour! * 60 + p.minute!;
|
||||||
});
|
state.endTime.value = "${p.hour}:${p.minute!}";
|
||||||
});
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Container(height: 10.h),
|
Container(height: 10.h),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -2,13 +2,16 @@ import 'package:date_format/date_format.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/style/default_style.dart';
|
// import 'package:flutter_pickers/style/default_style.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/app_settings/app_colors.dart';
|
import 'package:star_lock/app_settings/app_colors.dart';
|
||||||
import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart';
|
import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/default_style.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/storage.dart';
|
import 'package:star_lock/tools/storage.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
@ -329,8 +332,6 @@ class _PasswordKeyPerpetualPageState extends State<PasswordKeyPerpetualPage> {
|
|||||||
state.loopFailureDate.value =
|
state.loopFailureDate.value =
|
||||||
"${formatDate(state.failureDateTime.value, [HH])}:00";
|
"${formatDate(state.failureDateTime.value, [HH])}:00";
|
||||||
state.loopEndHours.value = p.hour!;
|
state.loopEndHours.value = p.hour!;
|
||||||
// state.selectFailureDate.value =
|
|
||||||
// formatDate(state.failureDateTime.value, [HH]);
|
|
||||||
} else {
|
} else {
|
||||||
// 处理日期不合法的情况,可以使用默认值或者其他策略
|
// 处理日期不合法的情况,可以使用默认值或者其他策略
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
import '../../../../appRouters.dart';
|
import '../../../../appRouters.dart';
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
@ -18,7 +19,8 @@ import 'addRemoteControl_logic.dart';
|
|||||||
class AddRemoteControlPage extends StatefulWidget {
|
class AddRemoteControlPage extends StatefulWidget {
|
||||||
final String seletType;
|
final String seletType;
|
||||||
|
|
||||||
const AddRemoteControlPage({Key? key, required this.seletType}) : super(key: key);
|
const AddRemoteControlPage({Key? key, required this.seletType})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AddRemoteControlPage> createState() => _AddRemoteControlPageState();
|
State<AddRemoteControlPage> createState() => _AddRemoteControlPageState();
|
||||||
@ -30,7 +32,6 @@ class _AddRemoteControlPageState extends State<AddRemoteControlPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
return indexChangeWidget();
|
return indexChangeWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,8 +43,10 @@ class _AddRemoteControlPageState extends State<AddRemoteControlPage> {
|
|||||||
// return sendElectronicKeySucceed();
|
// return sendElectronicKeySucceed();
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -53,8 +56,10 @@ class _AddRemoteControlPageState extends State<AddRemoteControlPage> {
|
|||||||
// 限时
|
// 限时
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
keyTimeLimitWidget(),
|
keyTimeLimitWidget(),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
@ -66,18 +71,24 @@ class _AddRemoteControlPageState extends State<AddRemoteControlPage> {
|
|||||||
// 循环
|
// 循环
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
perpetualKeyWidget(TranslationLoader.lanKeys!.name!.tr,
|
perpetualKeyWidget(
|
||||||
TranslationLoader.lanKeys!.pleaseEnter!.tr, state.nameController),
|
TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
TranslationLoader.lanKeys!.pleaseEnter!.tr,
|
||||||
|
state.nameController),
|
||||||
CommonItem(
|
CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr,
|
leftTitel: TranslationLoader.lanKeys!.periodValidity!.tr,
|
||||||
rightTitle: "",
|
rightTitle: "",
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
action: () async {
|
action: () async {
|
||||||
Map result = await Get.toNamed(Routers.electronicKeyPeriodValidityPage);
|
Map result = await Get.toNamed(
|
||||||
|
Routers.electronicKeyPeriodValidityPage);
|
||||||
state.weekdaysList.value = result['validityValue'];
|
state.weekdaysList.value = result['validityValue'];
|
||||||
state.effectiveDateTime.value = result['starDate'].millisecondsSinceEpoch;
|
state.effectiveDateTime.value =
|
||||||
state.failureDateTime.value = result['endDate'].millisecondsSinceEpoch;
|
result['starDate'].millisecondsSinceEpoch;
|
||||||
print('得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}');
|
state.failureDateTime.value =
|
||||||
|
result['endDate'].millisecondsSinceEpoch;
|
||||||
|
print(
|
||||||
|
'得到的有效期数据:${state.weekdaysList.value} == ${state.effectiveDateTime.value} == ${state.failureDateTime.value}');
|
||||||
}),
|
}),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
keyBottomWidget()
|
keyBottomWidget()
|
||||||
@ -117,13 +128,17 @@ class _AddRemoteControlPageState extends State<AddRemoteControlPage> {
|
|||||||
action: () async {
|
action: () async {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.beginTime.value = '${p.year}-${p.month!.toString().padLeft(2,'0')}-${p.day!.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}';
|
state.beginTime.value =
|
||||||
state.beginTimeTimestamp.value = DateTime.parse(state.beginTime.value).millisecondsSinceEpoch.toString();
|
'${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}';
|
||||||
});
|
state.beginTimeTimestamp.value =
|
||||||
});
|
DateTime.parse(state.beginTime.value)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Obx(() => CommonItem(
|
Obx(() => CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
leftTitel: TranslationLoader.lanKeys!.failureTime!.tr,
|
||||||
@ -132,13 +147,17 @@ class _AddRemoteControlPageState extends State<AddRemoteControlPage> {
|
|||||||
action: () {
|
action: () {
|
||||||
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
Pickers.showDatePicker(context, mode: DateMode.YMDHM,
|
||||||
onConfirm: (p) {
|
onConfirm: (p) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
state.endTime.value = '${p.year}-${p.month!.toString().padLeft(2,'0')}-${p.day!.toString().padLeft(2,'0')} ${p.hour!.toString().padLeft(2,'0')}:${p.minute!.toString().padLeft(2,'0')}';
|
state.endTime.value =
|
||||||
state.endTimeTimestamp.value = DateTime.parse(state.endTime.value).millisecondsSinceEpoch.toString();
|
'${p.year}-${p.month!.toString().padLeft(2, '0')}-${p.day!.toString().padLeft(2, '0')} ${p.hour!.toString().padLeft(2, '0')}:${p.minute!.toString().padLeft(2, '0')}';
|
||||||
});
|
state.endTimeTimestamp.value =
|
||||||
});
|
DateTime.parse(state.endTime.value)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
})),
|
})),
|
||||||
Container(height: 10.h),
|
Container(height: 10.h),
|
||||||
],
|
],
|
||||||
@ -156,23 +175,23 @@ class _AddRemoteControlPageState extends State<AddRemoteControlPage> {
|
|||||||
// rightWidget: SizedBox(
|
// rightWidget: SizedBox(
|
||||||
// width: 60.w, height: 50.h, child: _isStressFingerprint())),
|
// width: 60.w, height: 50.h, child: _isStressFingerprint())),
|
||||||
SizedBox(height: 30.h),
|
SizedBox(height: 30.h),
|
||||||
SubmitBtn(btnName: TranslationLoader.lanKeys!.next!.tr, onClick: () async {
|
SubmitBtn(
|
||||||
|
btnName: TranslationLoader.lanKeys!.next!.tr,
|
||||||
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
onClick: () async {
|
||||||
if(isDemoMode == false){
|
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
|
||||||
// print("state.seletType:${state.seletType.value}");
|
if (isDemoMode == false) {
|
||||||
if(state.nameController.text.isEmpty){
|
// print("state.seletType:${state.seletType.value}");
|
||||||
Toast.show(msg: "请输入姓名");
|
if (state.nameController.text.isEmpty) {
|
||||||
return;
|
Toast.show(msg: "请输入姓名");
|
||||||
}
|
return;
|
||||||
Toast.show(msg: "请确保在设备附近");
|
}
|
||||||
// logic.addFingerprintsData();
|
Toast.show(msg: "请确保在设备附近");
|
||||||
}else{
|
// logic.addFingerprintsData();
|
||||||
// Get.toNamed(Routers.seletLockTypePage);
|
} else {
|
||||||
Toast.show(msg: "演示模式");
|
// Get.toNamed(Routers.seletLockTypePage);
|
||||||
}
|
Toast.show(msg: "演示模式");
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -293,5 +312,4 @@ class _AddRemoteControlPageState extends State<AddRemoteControlPage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get_utils/get_utils.dart';
|
import 'package:get/get_utils/get_utils.dart';
|
||||||
import 'package:star_lock/appRouters.dart';
|
import 'package:star_lock/appRouters.dart';
|
||||||
@ -10,6 +10,8 @@ import 'package:star_lock/app_settings/app_colors.dart';
|
|||||||
import 'package:star_lock/network/api_repository.dart';
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
import 'package:star_lock/tools/commonItem.dart';
|
import 'package:star_lock/tools/commonItem.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/submitBtn.dart';
|
import 'package:star_lock/tools/submitBtn.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
import 'package:star_lock/translations/trans_lib.dart';
|
import 'package:star_lock/translations/trans_lib.dart';
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart';
|
||||||
import 'package:star_lock/mine/mineSet/authorizedAdministrator/authorizedAdminListEntity.dart';
|
import 'package:star_lock/mine/mineSet/authorizedAdministrator/authorizedAdminListEntity.dart';
|
||||||
import 'package:star_lock/network/api_repository.dart';
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
import '../../../../../app_settings/app_colors.dart';
|
import '../../../../../app_settings/app_colors.dart';
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_pickers/pickers.dart';
|
// import 'package:flutter_pickers/pickers.dart';
|
||||||
import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyDetail/keyOperationRecordEntity.dart';
|
||||||
import 'package:star_lock/mine/mineSet/lockUserManage/expireLockList/expireLockListEntity.dart';
|
import 'package:star_lock/mine/mineSet/lockUserManage/expireLockList/expireLockListEntity.dart';
|
||||||
import 'package:star_lock/network/api_repository.dart';
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/pickers.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
import 'package:star_lock/tools/toast.dart';
|
import 'package:star_lock/tools/toast.dart';
|
||||||
|
|
||||||
import '../../../../../app_settings/app_colors.dart';
|
import '../../../../../app_settings/app_colors.dart';
|
||||||
|
|||||||
4311
star_lock/lib/tools/pickers/address_picker/locations_data.dart
Normal file
4311
star_lock/lib/tools/pickers/address_picker/locations_data.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,462 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/picker_style.dart';
|
||||||
|
// import 'package:flutter_pickers/style/picker_style.dart';
|
||||||
|
|
||||||
|
import '../locations_data.dart';
|
||||||
|
|
||||||
|
typedef AddressCallback(String province, String city, String? town);
|
||||||
|
|
||||||
|
/// 自定义 地区选择器
|
||||||
|
/// [initProvince] 初始化 省
|
||||||
|
/// [initCity] 初始化 市
|
||||||
|
/// [initTown] 初始化 区
|
||||||
|
/// [onChanged] 选择器发生变动
|
||||||
|
/// [onConfirm] 选择器提交
|
||||||
|
/// [addAllItem] 市、区是否添加 '全部' 选项 默认:true
|
||||||
|
class AddressPickerRoute<T> extends PopupRoute<T> {
|
||||||
|
AddressPickerRoute({
|
||||||
|
required this.addAllItem,
|
||||||
|
required this.pickerStyle,
|
||||||
|
required this.initProvince,
|
||||||
|
required this.initCity,
|
||||||
|
this.initTown,
|
||||||
|
this.onChanged,
|
||||||
|
this.onConfirm,
|
||||||
|
this.onCancel,
|
||||||
|
this.theme,
|
||||||
|
this.barrierLabel,
|
||||||
|
RouteSettings? settings,
|
||||||
|
}) : super(settings: settings);
|
||||||
|
|
||||||
|
late final String initProvince, initCity;
|
||||||
|
final String? initTown;
|
||||||
|
final AddressCallback? onChanged;
|
||||||
|
final AddressCallback? onConfirm;
|
||||||
|
final Function(bool isCancel)? onCancel;
|
||||||
|
final ThemeData? theme;
|
||||||
|
final bool addAllItem;
|
||||||
|
|
||||||
|
late final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 200);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get barrierDismissible => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool didPop(T? result) {
|
||||||
|
if (onCancel != null) {
|
||||||
|
if (result == null) {
|
||||||
|
onCancel!(false);
|
||||||
|
} else if (!(result as bool)) {
|
||||||
|
onCancel!(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String? barrierLabel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color get barrierColor => Colors.black54;
|
||||||
|
|
||||||
|
AnimationController? _animationController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
AnimationController createAnimationController() {
|
||||||
|
assert(_animationController == null);
|
||||||
|
_animationController =
|
||||||
|
BottomSheet.createAnimationController(navigator!.overlay!);
|
||||||
|
return _animationController!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
Widget bottomSheet = MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeTop: true,
|
||||||
|
child: _PickerContentView(
|
||||||
|
initProvince: initProvince,
|
||||||
|
initCity: initCity,
|
||||||
|
initTown: initTown,
|
||||||
|
addAllItem: addAllItem,
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
route: this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (theme != null) {
|
||||||
|
bottomSheet = Theme(data: theme!, child: bottomSheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bottomSheet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerContentView extends StatefulWidget {
|
||||||
|
_PickerContentView({
|
||||||
|
Key? key,
|
||||||
|
required this.initProvince,
|
||||||
|
required this.initCity,
|
||||||
|
this.initTown,
|
||||||
|
required this.pickerStyle,
|
||||||
|
required this.addAllItem,
|
||||||
|
required this.route,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String initProvince, initCity;
|
||||||
|
final String? initTown;
|
||||||
|
final AddressPickerRoute route;
|
||||||
|
final bool addAllItem;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _PickerState(this.initProvince,
|
||||||
|
this.initCity, this.initTown, this.addAllItem, this.pickerStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerState extends State<_PickerContentView> {
|
||||||
|
final PickerStyle _pickerStyle;
|
||||||
|
late String _currentProvince, _currentCity;
|
||||||
|
String? _currentTown;
|
||||||
|
var cities = [];
|
||||||
|
var towns = [];
|
||||||
|
var provinces = [];
|
||||||
|
|
||||||
|
// 是否显示县级
|
||||||
|
bool hasTown = true;
|
||||||
|
|
||||||
|
// 是否添加全部
|
||||||
|
late final bool addAllItem;
|
||||||
|
|
||||||
|
AnimationController? controller;
|
||||||
|
Animation<double>? animation;
|
||||||
|
|
||||||
|
late FixedExtentScrollController provinceScrollCtrl,
|
||||||
|
cityScrollCtrl,
|
||||||
|
townScrollCtrl;
|
||||||
|
|
||||||
|
_PickerState(this._currentProvince, this._currentCity, this._currentTown,
|
||||||
|
this.addAllItem, this._pickerStyle) {
|
||||||
|
provinces = Address.provinces;
|
||||||
|
hasTown = this._currentTown != null;
|
||||||
|
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
provinceScrollCtrl.dispose();
|
||||||
|
cityScrollCtrl.dispose();
|
||||||
|
townScrollCtrl.dispose();
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: AnimatedBuilder(
|
||||||
|
animation: widget.route.animation!,
|
||||||
|
builder: (BuildContext context, Widget? child) {
|
||||||
|
return ClipRect(
|
||||||
|
child: CustomSingleChildLayout(
|
||||||
|
delegate: _BottomPickerLayout(
|
||||||
|
widget.route.animation!.value, this._pickerStyle),
|
||||||
|
child: GestureDetector(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: _renderPickerView(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
Address.addAllItem = addAllItem;
|
||||||
|
int pindex = 0;
|
||||||
|
int cindex = 0;
|
||||||
|
int tindex = 0;
|
||||||
|
pindex = provinces.indexWhere((p) => p == _currentProvince);
|
||||||
|
pindex = pindex >= 0 ? pindex : 0;
|
||||||
|
String? selectedProvince = provinces[pindex];
|
||||||
|
if (selectedProvince != null) {
|
||||||
|
_currentProvince = selectedProvince;
|
||||||
|
|
||||||
|
cities = Address.getCities(selectedProvince);
|
||||||
|
|
||||||
|
cindex = cities.indexWhere((c) => c['name'] == _currentCity);
|
||||||
|
cindex = cindex >= 0 ? cindex : 0;
|
||||||
|
_currentCity = cities[cindex]['name'];
|
||||||
|
|
||||||
|
// print('longer >>> 外面接到的$cities');
|
||||||
|
|
||||||
|
if (hasTown) {
|
||||||
|
towns = Address.getTowns(cities[cindex]['cityCode']);
|
||||||
|
tindex = towns.indexWhere((t) => t == _currentTown);
|
||||||
|
tindex = tindex >= 0 ? tindex : 0;
|
||||||
|
if (towns.length == 0) {
|
||||||
|
_currentTown = '';
|
||||||
|
} else {
|
||||||
|
_currentTown = towns[tindex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provinceScrollCtrl = new FixedExtentScrollController(initialItem: pindex);
|
||||||
|
cityScrollCtrl = new FixedExtentScrollController(initialItem: cindex);
|
||||||
|
townScrollCtrl = new FixedExtentScrollController(initialItem: tindex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setProvince(int index) {
|
||||||
|
String selectedProvince = provinces[index];
|
||||||
|
// print('longer >>> index:$index _currentProvince:$_currentProvince selectedProvince:$selectedProvince ');
|
||||||
|
|
||||||
|
if (_currentProvince != selectedProvince) {
|
||||||
|
setState(() {
|
||||||
|
_currentProvince = selectedProvince;
|
||||||
|
|
||||||
|
cities = Address.getCities(selectedProvince);
|
||||||
|
// print('longer >>> 返回的城市数据:$cities');
|
||||||
|
|
||||||
|
_currentCity = cities[0]['name'];
|
||||||
|
cityScrollCtrl.jumpToItem(0);
|
||||||
|
if (hasTown) {
|
||||||
|
towns = Address.getTowns(cities[0]['cityCode']);
|
||||||
|
_currentTown = towns[0];
|
||||||
|
townScrollCtrl.jumpToItem(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_notifyLocationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setCity(int index) {
|
||||||
|
index = cities.length > index ? index : 0;
|
||||||
|
String selectedCity = cities[index]['name'];
|
||||||
|
if (_currentCity != selectedCity) {
|
||||||
|
setState(() {
|
||||||
|
_currentCity = selectedCity;
|
||||||
|
if (hasTown) {
|
||||||
|
towns = Address.getTowns(cities[index]['cityCode']);
|
||||||
|
_currentTown = towns.isNotEmpty ? towns[0] : '';
|
||||||
|
townScrollCtrl.jumpToItem(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_notifyLocationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setTown(int index) {
|
||||||
|
index = towns.length > index ? index : 0;
|
||||||
|
String selectedTown = towns[index];
|
||||||
|
if (_currentTown != selectedTown) {
|
||||||
|
_currentTown = selectedTown;
|
||||||
|
_notifyLocationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _notifyLocationChanged() {
|
||||||
|
if (widget.route.onChanged != null) {
|
||||||
|
widget.route.onChanged!(_currentProvince, _currentCity, _currentTown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double _pickerFontSize(String text) {
|
||||||
|
double ratio = hasTown ? 0.0 : 2.0;
|
||||||
|
if (text.length <= 6) {
|
||||||
|
return 18.0;
|
||||||
|
} else if (text.length < 9) {
|
||||||
|
return 16.0 + ratio;
|
||||||
|
} else if (text.length < 13) {
|
||||||
|
return 12.0 + ratio;
|
||||||
|
} else {
|
||||||
|
return 10.0 + ratio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderPickerView() {
|
||||||
|
Widget itemView = _renderItemView();
|
||||||
|
|
||||||
|
if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) {
|
||||||
|
return itemView;
|
||||||
|
}
|
||||||
|
List<Widget> viewList = <Widget>[];
|
||||||
|
if (_pickerStyle.showTitleBar) {
|
||||||
|
viewList.add(_titleView());
|
||||||
|
}
|
||||||
|
if (_pickerStyle.menu != null) {
|
||||||
|
viewList.add(_pickerStyle.menu!);
|
||||||
|
}
|
||||||
|
viewList.add(itemView);
|
||||||
|
|
||||||
|
return Column(children: viewList);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderItemView() {
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerHeight,
|
||||||
|
color: _pickerStyle.backgroundColor,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: CupertinoPicker.builder(
|
||||||
|
scrollController: provinceScrollCtrl,
|
||||||
|
selectionOverlay: _pickerStyle.itemOverlay,
|
||||||
|
itemExtent: _pickerStyle.pickerItemHeight,
|
||||||
|
onSelectedItemChanged: (int index) {
|
||||||
|
_setProvince(index);
|
||||||
|
},
|
||||||
|
childCount: Address.provinces.length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
String text = Address.provinces[index];
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(text,
|
||||||
|
style: TextStyle(
|
||||||
|
color: _pickerStyle.textColor,
|
||||||
|
fontSize:
|
||||||
|
_pickerStyle.textSize ?? _pickerFontSize(text),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: CupertinoPicker.builder(
|
||||||
|
scrollController: cityScrollCtrl,
|
||||||
|
selectionOverlay: _pickerStyle.itemOverlay,
|
||||||
|
itemExtent: _pickerStyle.pickerItemHeight,
|
||||||
|
onSelectedItemChanged: (int index) {
|
||||||
|
_setCity(index);
|
||||||
|
},
|
||||||
|
childCount: cities.length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
String text = cities[index]['name'];
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text('$text',
|
||||||
|
style: TextStyle(
|
||||||
|
color: _pickerStyle.textColor,
|
||||||
|
fontSize:
|
||||||
|
_pickerStyle.textSize ?? _pickerFontSize(text),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
hasTown
|
||||||
|
? Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: CupertinoPicker.builder(
|
||||||
|
scrollController: townScrollCtrl,
|
||||||
|
selectionOverlay: _pickerStyle.itemOverlay,
|
||||||
|
itemExtent: _pickerStyle.pickerItemHeight,
|
||||||
|
onSelectedItemChanged: (int index) {
|
||||||
|
_setTown(index);
|
||||||
|
},
|
||||||
|
childCount: towns.length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
String text = towns[index];
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(text,
|
||||||
|
style: TextStyle(
|
||||||
|
color: _pickerStyle.textColor,
|
||||||
|
fontSize: _pickerStyle.textSize ??
|
||||||
|
_pickerFontSize(text),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
: SizedBox()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择器上面的view
|
||||||
|
Widget _titleView() {
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerTitleHeight,
|
||||||
|
decoration: _pickerStyle.headDecoration,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
/// 取消按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () => Navigator.pop(context, false),
|
||||||
|
child: _pickerStyle.cancelButton),
|
||||||
|
|
||||||
|
/// 标题
|
||||||
|
Expanded(child: _pickerStyle.title),
|
||||||
|
|
||||||
|
/// 确认按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.route.onConfirm != null) {
|
||||||
|
widget.route.onConfirm!(
|
||||||
|
_currentProvince, _currentCity, _currentTown);
|
||||||
|
}
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
child: _pickerStyle.commitButton)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BottomPickerLayout extends SingleChildLayoutDelegate {
|
||||||
|
_BottomPickerLayout(this.progress, this.pickerStyle);
|
||||||
|
|
||||||
|
final double progress;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
||||||
|
double maxHeight = pickerStyle.pickerHeight;
|
||||||
|
if (pickerStyle.showTitleBar) {
|
||||||
|
maxHeight += pickerStyle.pickerTitleHeight;
|
||||||
|
}
|
||||||
|
if (pickerStyle.menu != null) {
|
||||||
|
maxHeight += pickerStyle.menuHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoxConstraints(
|
||||||
|
minWidth: constraints.maxWidth,
|
||||||
|
maxWidth: constraints.maxWidth,
|
||||||
|
minHeight: 0.0,
|
||||||
|
maxHeight: maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Offset getPositionForChild(Size size, Size childSize) {
|
||||||
|
double height = size.height - childSize.height * progress;
|
||||||
|
return Offset(0.0, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRelayout(_BottomPickerLayout oldDelegate) {
|
||||||
|
return progress != oldDelegate.progress;
|
||||||
|
}
|
||||||
|
}
|
||||||
76
star_lock/lib/tools/pickers/more_pickers/init_data.dart
Normal file
76
star_lock/lib/tools/pickers/more_pickers/init_data.dart
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
enum PickerDataType {
|
||||||
|
sex, // 性别
|
||||||
|
education, // 学历
|
||||||
|
subject, // 学科
|
||||||
|
constellation, // 星座
|
||||||
|
zodiac, // 生肖
|
||||||
|
ethnicity, // 名族
|
||||||
|
}
|
||||||
|
|
||||||
|
var pickerData = {
|
||||||
|
PickerDataType.sex: ['不限', '男', '女'],
|
||||||
|
PickerDataType.education: ["高中以下", "高中", "大专", "本科", "硕士", "博士", "博士后", '其它'],
|
||||||
|
PickerDataType.subject: ["语文", "数学", "英语", "物理", "化学", "生物", "政治", "地理", "历史"],
|
||||||
|
PickerDataType.constellation: ["水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座"],
|
||||||
|
PickerDataType.zodiac: ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'],
|
||||||
|
PickerDataType.ethnicity: [
|
||||||
|
'汉族',
|
||||||
|
'蒙古族',
|
||||||
|
'回族',
|
||||||
|
'藏族',
|
||||||
|
'维吾尔族',
|
||||||
|
'苗族',
|
||||||
|
'彝族',
|
||||||
|
'壮族',
|
||||||
|
'布依族',
|
||||||
|
'朝鲜族',
|
||||||
|
'满族',
|
||||||
|
'侗族',
|
||||||
|
'瑶族',
|
||||||
|
'白族',
|
||||||
|
'土家族',
|
||||||
|
'哈尼族',
|
||||||
|
'哈萨克族',
|
||||||
|
'傣族',
|
||||||
|
'黎族',
|
||||||
|
'傈僳族',
|
||||||
|
'佤族',
|
||||||
|
'畲族',
|
||||||
|
'高山族',
|
||||||
|
'拉祜族',
|
||||||
|
'水族',
|
||||||
|
'东乡族',
|
||||||
|
'纳西族',
|
||||||
|
'景颇族',
|
||||||
|
'柯尔克孜族',
|
||||||
|
'土族',
|
||||||
|
'达斡尔族',
|
||||||
|
'仫佬族',
|
||||||
|
'羌族',
|
||||||
|
'布朗族',
|
||||||
|
'撒拉族',
|
||||||
|
'毛难族',
|
||||||
|
'仡佬族',
|
||||||
|
'锡伯族',
|
||||||
|
'阿昌族',
|
||||||
|
'普米族',
|
||||||
|
'塔吉克族',
|
||||||
|
'怒族',
|
||||||
|
'乌孜别克族',
|
||||||
|
'俄罗斯族',
|
||||||
|
'鄂温克族',
|
||||||
|
'崩龙族',
|
||||||
|
'保安族',
|
||||||
|
'裕固族',
|
||||||
|
'京族',
|
||||||
|
'塔塔尔族',
|
||||||
|
'独龙族',
|
||||||
|
'鄂伦春族',
|
||||||
|
'赫哲族',
|
||||||
|
'门巴族',
|
||||||
|
'珞巴族',
|
||||||
|
'基诺族',
|
||||||
|
'其他',
|
||||||
|
'外国血统中国人士'
|
||||||
|
],
|
||||||
|
};
|
||||||
@ -0,0 +1,493 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/picker_style.dart';
|
||||||
|
// import 'package:flutter_pickers/style/picker_style.dart';
|
||||||
|
|
||||||
|
typedef MultipleLinkCallback(List res, List<int> position);
|
||||||
|
|
||||||
|
/// 多项选择器
|
||||||
|
/// 有关联
|
||||||
|
class MultipleLinkPickerRoute<T> extends PopupRoute<T> {
|
||||||
|
MultipleLinkPickerRoute({
|
||||||
|
required this.pickerStyle,
|
||||||
|
required this.data,
|
||||||
|
required this.selectData,
|
||||||
|
required this.columeNum,
|
||||||
|
this.suffix,
|
||||||
|
this.onChanged,
|
||||||
|
this.onConfirm,
|
||||||
|
this.onCancel,
|
||||||
|
this.theme,
|
||||||
|
this.barrierLabel,
|
||||||
|
RouteSettings? settings,
|
||||||
|
}) : super(settings: settings);
|
||||||
|
|
||||||
|
final Map data;
|
||||||
|
final int columeNum;
|
||||||
|
final List selectData;
|
||||||
|
final List? suffix;
|
||||||
|
final MultipleLinkCallback? onChanged;
|
||||||
|
final MultipleLinkCallback? onConfirm;
|
||||||
|
final Function(bool isCancel)? onCancel;
|
||||||
|
final ThemeData? theme;
|
||||||
|
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 200);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get barrierDismissible => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool didPop(T? result) {
|
||||||
|
if (onCancel != null) {
|
||||||
|
if (result == null) {
|
||||||
|
onCancel!(false);
|
||||||
|
} else if (!(result as bool)) {
|
||||||
|
onCancel!(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String? barrierLabel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color get barrierColor => Colors.black54;
|
||||||
|
|
||||||
|
late AnimationController _animationController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
AnimationController createAnimationController() {
|
||||||
|
_animationController =
|
||||||
|
BottomSheet.createAnimationController(navigator!.overlay!);
|
||||||
|
return _animationController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
Widget bottomSheet = MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeTop: true,
|
||||||
|
child: _PickerContentView(
|
||||||
|
data: data,
|
||||||
|
columeNum: columeNum,
|
||||||
|
selectData: selectData,
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
route: this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (theme != null) {
|
||||||
|
bottomSheet = Theme(data: theme!, child: bottomSheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bottomSheet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerContentView extends StatefulWidget {
|
||||||
|
_PickerContentView({
|
||||||
|
Key? key,
|
||||||
|
required this.data,
|
||||||
|
required this.columeNum,
|
||||||
|
required this.pickerStyle,
|
||||||
|
required this.selectData,
|
||||||
|
required this.route,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final Map data;
|
||||||
|
final int columeNum;
|
||||||
|
final List selectData;
|
||||||
|
final MultipleLinkPickerRoute route;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _PickerState(
|
||||||
|
this.data, this.selectData, this.pickerStyle, this.columeNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerState extends State<_PickerContentView> {
|
||||||
|
final PickerStyle _pickerStyle;
|
||||||
|
|
||||||
|
// 没有数据时占位字符
|
||||||
|
static const placeData = '';
|
||||||
|
|
||||||
|
/// 选中数据
|
||||||
|
late List _selectData;
|
||||||
|
|
||||||
|
/// 选中数据下标
|
||||||
|
late List<int> _selectDataPosition;
|
||||||
|
|
||||||
|
/// 原始数据
|
||||||
|
Map _data;
|
||||||
|
|
||||||
|
/// 有多少列
|
||||||
|
final int _columeNum;
|
||||||
|
|
||||||
|
/// 所有item 对应的数据
|
||||||
|
late List<List> _columnData = [];
|
||||||
|
|
||||||
|
AnimationController? controller;
|
||||||
|
Animation<double>? animation;
|
||||||
|
|
||||||
|
List<FixedExtentScrollController> scrollCtrl = [];
|
||||||
|
|
||||||
|
// 选择器 高度 单独提出来,用来解决修改数据 不及时更新的BUG
|
||||||
|
late double pickerItemHeight;
|
||||||
|
|
||||||
|
_PickerState(
|
||||||
|
this._data, List mSelectData, this._pickerStyle, this._columeNum) {
|
||||||
|
this.pickerItemHeight = _pickerStyle.pickerItemHeight;
|
||||||
|
// 已选择器数据为准,因为初始化数据有可能和选择器对不上
|
||||||
|
this._selectData = [];
|
||||||
|
this._selectDataPosition = [];
|
||||||
|
for (int i = 0; i < _columeNum; ++i) {
|
||||||
|
if (i >= mSelectData.length) {
|
||||||
|
this._selectData.add('');
|
||||||
|
} else {
|
||||||
|
this._selectData.add(mSelectData[i]);
|
||||||
|
}
|
||||||
|
this._selectDataPosition.add(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_init(mSelectData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
scrollCtrl.forEach((element) {
|
||||||
|
element.dispose();
|
||||||
|
});
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: AnimatedBuilder(
|
||||||
|
animation: widget.route.animation!,
|
||||||
|
builder: (BuildContext context, Widget? child) {
|
||||||
|
return ClipRect(
|
||||||
|
child: CustomSingleChildLayout(
|
||||||
|
delegate: _BottomPickerLayout(widget.route.animation!.value,
|
||||||
|
pickerStyle: _pickerStyle),
|
||||||
|
child: GestureDetector(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: _renderPickerView(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_init(List mSelectData) {
|
||||||
|
int pindex;
|
||||||
|
scrollCtrl.clear();
|
||||||
|
_columnData.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < _columeNum; ++i) {
|
||||||
|
pindex = 0;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
/// 第一列
|
||||||
|
pindex = _data.keys.toList().indexOf(_selectData[i]);
|
||||||
|
if (pindex < 0) {
|
||||||
|
_selectData[i] = _data.keys.first;
|
||||||
|
pindex = 0;
|
||||||
|
}
|
||||||
|
_selectDataPosition[i] = pindex;
|
||||||
|
|
||||||
|
_columnData.add(_data.keys.toList());
|
||||||
|
} else {
|
||||||
|
/// 其他列
|
||||||
|
dynamic date = findNextData(i);
|
||||||
|
// print('longer 第$i列 >>> $date');
|
||||||
|
|
||||||
|
if (date is Map) {
|
||||||
|
pindex = date.keys.toList().indexOf(_selectData[i]);
|
||||||
|
if (pindex < 0) {
|
||||||
|
_selectData[i] = date.keys.first;
|
||||||
|
pindex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_columnData.add(date.keys.toList());
|
||||||
|
} else if (date is List) {
|
||||||
|
pindex = date.indexOf(_selectData[i]);
|
||||||
|
if (pindex < 0) {
|
||||||
|
_selectData[i] = date.first;
|
||||||
|
pindex = 0;
|
||||||
|
}
|
||||||
|
_columnData.add(date);
|
||||||
|
} else {
|
||||||
|
_selectData[i] = date;
|
||||||
|
pindex = 0;
|
||||||
|
|
||||||
|
_columnData.add([date]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectDataPosition[i] = pindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollCtrl.add(FixedExtentScrollController(initialItem: pindex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [position] 变动的列
|
||||||
|
/// [selectIndex] 对应列选中的index
|
||||||
|
/// [jump] 是否需要jumpToItem
|
||||||
|
void _setPicker(int position, int selectIndex, bool jump) {
|
||||||
|
// 得到新的选中的数据
|
||||||
|
var selectValue = _columnData[position][selectIndex];
|
||||||
|
// 更新选中数据
|
||||||
|
_selectData[position] = selectValue;
|
||||||
|
_selectDataPosition[position] = selectIndex;
|
||||||
|
if (jump) {
|
||||||
|
scrollCtrl[position].jumpToItem(selectIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 如果不是最后一列
|
||||||
|
/// 数据的变动都会造成剩下列的更新
|
||||||
|
if (position < _columeNum - 1) {
|
||||||
|
// 先更新下一列所有数据
|
||||||
|
// 如果这一列的所有数据都为空,下列直接也设为空数据(优化)
|
||||||
|
if (_columnData[position].length == 1 &&
|
||||||
|
_columnData[position].first == placeData) {
|
||||||
|
_columnData[position + 1] = [placeData];
|
||||||
|
} else {
|
||||||
|
_columnData[position + 1] = findColumeData(position + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 再次递归
|
||||||
|
_setPicker(position + 1, 0, true);
|
||||||
|
} else {
|
||||||
|
_notifyLocationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 找到对应位置的 下一列数据
|
||||||
|
/// return map list other
|
||||||
|
dynamic findNextData(int position) {
|
||||||
|
dynamic nextData;
|
||||||
|
|
||||||
|
for (int i = 0; i < position; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
// 肯定是map
|
||||||
|
nextData = _data[_selectData[0]];
|
||||||
|
} else {
|
||||||
|
// 肯定是map
|
||||||
|
dynamic data = nextData[_selectData[i]];
|
||||||
|
|
||||||
|
if (data is Map) {
|
||||||
|
nextData = data;
|
||||||
|
} else if (data is List) {
|
||||||
|
nextData = data;
|
||||||
|
} else {
|
||||||
|
// 遍历到最后会返回该值
|
||||||
|
nextData = [data];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// print('longer i:$i >>> $nextData');
|
||||||
|
|
||||||
|
/// 如果数据 还没有到最后 就 已经不是Map
|
||||||
|
if (!(nextData is Map) && (i < position - 1)) {
|
||||||
|
return [placeData];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 找到对应位置的数据
|
||||||
|
/// 比如 position = 2;
|
||||||
|
/// 就是找到第2列数据
|
||||||
|
/// return list
|
||||||
|
List findColumeData(int position) {
|
||||||
|
dynamic nextData;
|
||||||
|
for (int i = 0; i < position; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
// 肯定是map
|
||||||
|
nextData = _data[_selectData[0]];
|
||||||
|
} else {
|
||||||
|
// print(
|
||||||
|
// 'longer 选中 >>> ${_selectData.join('-')} 当前选中: ${_selectData[i]}');
|
||||||
|
// 肯定是map
|
||||||
|
dynamic data = nextData[_selectData[i]];
|
||||||
|
|
||||||
|
if (data is Map) {
|
||||||
|
nextData = data;
|
||||||
|
} else if (data is List) {
|
||||||
|
nextData = data;
|
||||||
|
} else {
|
||||||
|
// 遍历到最后会返回该值
|
||||||
|
nextData = [data];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// print('longer i:$i >>> $nextData');
|
||||||
|
|
||||||
|
/// 如果是map 并且是最后一列 返回他的key
|
||||||
|
if ((nextData is Map) && (i == position - 1)) {
|
||||||
|
return nextData.keys.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 如果数据 还没有到最后 就 已经不是Map
|
||||||
|
if (!(nextData is Map) && (i < position - 1)) {
|
||||||
|
// print('longer2 第:$position列之前返回数据 >>> $nextData');
|
||||||
|
return [placeData];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// print('longer 第:$position列返回数据 >>> $nextData');
|
||||||
|
return nextData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _notifyLocationChanged() {
|
||||||
|
setState(() {
|
||||||
|
/// FIX:https://github.com/flutter/flutter/issues/22999
|
||||||
|
pickerItemHeight =
|
||||||
|
_pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
|
||||||
|
});
|
||||||
|
if (widget.route.onChanged != null) {
|
||||||
|
widget.route.onChanged!(_selectData, _selectDataPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderPickerView() {
|
||||||
|
Widget itemView = _renderItemView();
|
||||||
|
|
||||||
|
if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) {
|
||||||
|
return itemView;
|
||||||
|
}
|
||||||
|
List<Widget> viewList = <Widget>[];
|
||||||
|
if (_pickerStyle.showTitleBar) {
|
||||||
|
viewList.add(_titleView());
|
||||||
|
}
|
||||||
|
if (_pickerStyle.menu != null) {
|
||||||
|
viewList.add(_pickerStyle.menu!);
|
||||||
|
}
|
||||||
|
viewList.add(itemView);
|
||||||
|
|
||||||
|
return Column(children: viewList);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderItemView() {
|
||||||
|
// 选择器
|
||||||
|
List<Widget> pickerList =
|
||||||
|
List.generate(_columeNum, (index) => pickerView(index)).toList();
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerHeight,
|
||||||
|
color: _pickerStyle.backgroundColor,
|
||||||
|
child: Row(children: pickerList),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget pickerView(int position) {
|
||||||
|
return Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||||
|
child: CupertinoPicker.builder(
|
||||||
|
scrollController: scrollCtrl[position],
|
||||||
|
itemExtent: pickerItemHeight,
|
||||||
|
selectionOverlay: _pickerStyle.itemOverlay,
|
||||||
|
onSelectedItemChanged: (int selectIndex) {
|
||||||
|
_setPicker(position, selectIndex, false);
|
||||||
|
},
|
||||||
|
childCount: _columnData[position].length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
// String text = _data[position][index].toString();
|
||||||
|
String suffix = '';
|
||||||
|
if (widget.route.suffix != null &&
|
||||||
|
position < widget.route.suffix!.length) {
|
||||||
|
suffix = widget.route.suffix![position];
|
||||||
|
}
|
||||||
|
|
||||||
|
String text = '${_columnData[position][index]}$suffix';
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(text,
|
||||||
|
style: TextStyle(
|
||||||
|
color: _pickerStyle.textColor,
|
||||||
|
fontSize: _pickerStyle.textSize ?? 18.0,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择器上面的view
|
||||||
|
Widget _titleView() {
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerTitleHeight,
|
||||||
|
decoration: _pickerStyle.headDecoration,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
/// 取消按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () => Navigator.pop(context, false),
|
||||||
|
child: _pickerStyle.cancelButton),
|
||||||
|
|
||||||
|
/// 标题
|
||||||
|
Expanded(child: _pickerStyle.title),
|
||||||
|
|
||||||
|
/// 确认按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.route.onConfirm != null) {
|
||||||
|
widget.route.onConfirm!(_selectData, _selectDataPosition);
|
||||||
|
}
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
child: _pickerStyle.commitButton)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BottomPickerLayout extends SingleChildLayoutDelegate {
|
||||||
|
_BottomPickerLayout(this.progress, {required this.pickerStyle});
|
||||||
|
|
||||||
|
final double progress;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
||||||
|
double maxHeight = pickerStyle.pickerHeight;
|
||||||
|
if (pickerStyle.showTitleBar) {
|
||||||
|
maxHeight += pickerStyle.pickerTitleHeight;
|
||||||
|
}
|
||||||
|
if (pickerStyle.menu != null) {
|
||||||
|
maxHeight += pickerStyle.menuHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoxConstraints(
|
||||||
|
minWidth: constraints.maxWidth,
|
||||||
|
maxWidth: constraints.maxWidth,
|
||||||
|
minHeight: 0.0,
|
||||||
|
maxHeight: maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Offset getPositionForChild(Size size, Size childSize) {
|
||||||
|
double height = size.height - childSize.height * progress;
|
||||||
|
return Offset(0.0, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRelayout(_BottomPickerLayout oldDelegate) {
|
||||||
|
return progress != oldDelegate.progress;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,332 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/picker_style.dart';
|
||||||
|
// import 'package:flutter_pickers/style/picker_style.dart';
|
||||||
|
|
||||||
|
typedef MultipleCallback(List res, List<int> position);
|
||||||
|
|
||||||
|
/// 多项选择器
|
||||||
|
/// 无关联
|
||||||
|
class MultiplePickerRoute<T> extends PopupRoute<T> {
|
||||||
|
MultiplePickerRoute({
|
||||||
|
required this.pickerStyle,
|
||||||
|
required this.data,
|
||||||
|
required this.selectData,
|
||||||
|
this.suffix,
|
||||||
|
this.onChanged,
|
||||||
|
this.onConfirm,
|
||||||
|
this.onCancel,
|
||||||
|
this.theme,
|
||||||
|
this.barrierLabel,
|
||||||
|
RouteSettings? settings,
|
||||||
|
}) : super(settings: settings);
|
||||||
|
|
||||||
|
final List<List> data;
|
||||||
|
final List selectData;
|
||||||
|
final List? suffix;
|
||||||
|
final MultipleCallback? onChanged;
|
||||||
|
final MultipleCallback? onConfirm;
|
||||||
|
final Function(bool isCancel)? onCancel;
|
||||||
|
final ThemeData? theme;
|
||||||
|
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 200);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get barrierDismissible => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool didPop(T? result) {
|
||||||
|
if (onCancel != null) {
|
||||||
|
if (result == null) {
|
||||||
|
onCancel!(false);
|
||||||
|
} else if (!(result as bool)) {
|
||||||
|
onCancel!(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String? barrierLabel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color get barrierColor => Colors.black54;
|
||||||
|
|
||||||
|
late AnimationController _animationController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
AnimationController createAnimationController() {
|
||||||
|
_animationController =
|
||||||
|
BottomSheet.createAnimationController(navigator!.overlay!);
|
||||||
|
return _animationController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
Widget bottomSheet = MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeTop: true,
|
||||||
|
child: _PickerContentView(
|
||||||
|
data: data,
|
||||||
|
selectData: selectData,
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
route: this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (theme != null) {
|
||||||
|
bottomSheet = Theme(data: theme!, child: bottomSheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bottomSheet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerContentView extends StatefulWidget {
|
||||||
|
_PickerContentView({
|
||||||
|
Key? key,
|
||||||
|
required this.data,
|
||||||
|
required this.pickerStyle,
|
||||||
|
required this.selectData,
|
||||||
|
required this.route,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final List<List> data;
|
||||||
|
final List selectData;
|
||||||
|
final MultiplePickerRoute route;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() =>
|
||||||
|
_PickerState(this.data, this.selectData, this.pickerStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerState extends State<_PickerContentView> {
|
||||||
|
final PickerStyle _pickerStyle;
|
||||||
|
late List _selectData;
|
||||||
|
late List<int> _selectDataPosition;
|
||||||
|
List<List> _data;
|
||||||
|
|
||||||
|
AnimationController? controller;
|
||||||
|
Animation<double>? animation;
|
||||||
|
|
||||||
|
List<FixedExtentScrollController> scrollCtrl = [];
|
||||||
|
|
||||||
|
_PickerState(this._data, List mSelectData, this._pickerStyle) {
|
||||||
|
// 已选择器数据为准,因为初始化数据有可能和选择器对不上
|
||||||
|
this._selectData = [];
|
||||||
|
this._selectDataPosition = [];
|
||||||
|
this._data.asMap().keys.forEach((index) {
|
||||||
|
if (index >= mSelectData.length) {
|
||||||
|
this._selectData.add('');
|
||||||
|
} else {
|
||||||
|
this._selectData.add(mSelectData[index]);
|
||||||
|
}
|
||||||
|
this._selectDataPosition.add(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
scrollCtrl.forEach((element) {
|
||||||
|
element.dispose();
|
||||||
|
});
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: AnimatedBuilder(
|
||||||
|
animation: widget.route.animation!,
|
||||||
|
builder: (BuildContext context, Widget? child) {
|
||||||
|
return ClipRect(
|
||||||
|
child: CustomSingleChildLayout(
|
||||||
|
delegate: _BottomPickerLayout(widget.route.animation!.value,
|
||||||
|
pickerStyle: _pickerStyle),
|
||||||
|
child: GestureDetector(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: _renderPickerView(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
int pindex;
|
||||||
|
scrollCtrl.clear();
|
||||||
|
|
||||||
|
this._data.asMap().keys.forEach((index) {
|
||||||
|
pindex = 0;
|
||||||
|
pindex = _data[index].indexWhere(
|
||||||
|
(element) => element.toString() == _selectData[index].toString());
|
||||||
|
// 如果没有匹配到选择器对应数据,我们得修改选择器选中数据 ,不然confirm 返回的事设置的数据
|
||||||
|
if (pindex < 0) {
|
||||||
|
_selectData[index] = _data[index][0];
|
||||||
|
pindex = 0;
|
||||||
|
}
|
||||||
|
_selectDataPosition[index] = pindex;
|
||||||
|
|
||||||
|
scrollCtrl.add(new FixedExtentScrollController(initialItem: pindex));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setPicker(int index, int selectIndex) {
|
||||||
|
var selectedName = _data[index][selectIndex];
|
||||||
|
|
||||||
|
// if (_selectData[index].toString() != selectedName.toString()) {
|
||||||
|
// setState(() {
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
_selectData[index] = selectedName;
|
||||||
|
_selectDataPosition[index] = selectIndex;
|
||||||
|
|
||||||
|
_notifyLocationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _notifyLocationChanged() {
|
||||||
|
if (widget.route.onChanged != null) {
|
||||||
|
widget.route.onChanged!(_selectData, _selectDataPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderPickerView() {
|
||||||
|
Widget itemView = _renderItemView();
|
||||||
|
|
||||||
|
if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) {
|
||||||
|
return itemView;
|
||||||
|
}
|
||||||
|
List<Widget> viewList = <Widget>[];
|
||||||
|
if (_pickerStyle.showTitleBar) {
|
||||||
|
viewList.add(_titleView());
|
||||||
|
}
|
||||||
|
if (_pickerStyle.menu != null) {
|
||||||
|
viewList.add(_pickerStyle.menu!);
|
||||||
|
}
|
||||||
|
viewList.add(itemView);
|
||||||
|
|
||||||
|
return Column(children: viewList);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderItemView() {
|
||||||
|
// 选择器
|
||||||
|
List<Widget> pickerList =
|
||||||
|
List.generate(this._data.length, (index) => pickerView(index)).toList();
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerHeight,
|
||||||
|
color: _pickerStyle.backgroundColor,
|
||||||
|
child: Row(children: pickerList),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget pickerView(int position) {
|
||||||
|
return Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||||
|
child: CupertinoPicker.builder(
|
||||||
|
scrollController: scrollCtrl[position],
|
||||||
|
selectionOverlay: _pickerStyle.itemOverlay,
|
||||||
|
itemExtent: _pickerStyle.pickerItemHeight,
|
||||||
|
onSelectedItemChanged: (int selectIndex) =>
|
||||||
|
_setPicker(position, selectIndex),
|
||||||
|
childCount: _data[position].length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
// String text = _data[position][index].toString();
|
||||||
|
String suffix = '';
|
||||||
|
if (widget.route.suffix != null &&
|
||||||
|
position < widget.route.suffix!.length) {
|
||||||
|
suffix = widget.route.suffix![position];
|
||||||
|
}
|
||||||
|
|
||||||
|
String text = '${_data[position][index]}$suffix';
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(text,
|
||||||
|
style: TextStyle(
|
||||||
|
color: _pickerStyle.textColor,
|
||||||
|
fontSize: _pickerStyle.textSize ?? 18,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择器上面的view
|
||||||
|
Widget _titleView() {
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerTitleHeight,
|
||||||
|
decoration: _pickerStyle.headDecoration,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
/// 取消按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () => Navigator.pop(context, false),
|
||||||
|
child: _pickerStyle.cancelButton),
|
||||||
|
|
||||||
|
/// 标题
|
||||||
|
Expanded(child: _pickerStyle.title),
|
||||||
|
|
||||||
|
/// 确认按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.route.onConfirm != null) {
|
||||||
|
widget.route.onConfirm!(_selectData, _selectDataPosition);
|
||||||
|
}
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
child: _pickerStyle.commitButton)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BottomPickerLayout extends SingleChildLayoutDelegate {
|
||||||
|
_BottomPickerLayout(this.progress, {required this.pickerStyle});
|
||||||
|
|
||||||
|
final double progress;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
||||||
|
double maxHeight = pickerStyle.pickerHeight;
|
||||||
|
if (pickerStyle.showTitleBar) {
|
||||||
|
maxHeight += pickerStyle.pickerTitleHeight;
|
||||||
|
}
|
||||||
|
if (pickerStyle.menu != null) {
|
||||||
|
maxHeight += pickerStyle.menuHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoxConstraints(
|
||||||
|
minWidth: constraints.maxWidth,
|
||||||
|
maxWidth: constraints.maxWidth,
|
||||||
|
minHeight: 0.0,
|
||||||
|
maxHeight: maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Offset getPositionForChild(Size size, Size childSize) {
|
||||||
|
double height = size.height - childSize.height * progress;
|
||||||
|
return Offset(0.0, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRelayout(_BottomPickerLayout oldDelegate) {
|
||||||
|
return progress != oldDelegate.progress;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,362 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/more_pickers/init_data.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/picker_style.dart';
|
||||||
|
// import 'package:flutter_pickers/more_pickers/init_data.dart';
|
||||||
|
// import 'package:flutter_pickers/style/picker_style.dart';
|
||||||
|
|
||||||
|
typedef SingleCallback(var data, int position);
|
||||||
|
|
||||||
|
class SinglePickerRoute<T> extends PopupRoute<T> {
|
||||||
|
SinglePickerRoute({
|
||||||
|
required this.data,
|
||||||
|
this.selectData,
|
||||||
|
this.suffix,
|
||||||
|
this.onChanged,
|
||||||
|
this.onConfirm,
|
||||||
|
this.onCancel,
|
||||||
|
required this.theme,
|
||||||
|
this.barrierLabel,
|
||||||
|
required this.pickerStyle,
|
||||||
|
RouteSettings? settings,
|
||||||
|
}) : super(settings: settings);
|
||||||
|
|
||||||
|
final dynamic selectData;
|
||||||
|
final dynamic data;
|
||||||
|
final SingleCallback? onChanged;
|
||||||
|
final SingleCallback? onConfirm;
|
||||||
|
final Function(bool isCancel)? onCancel;
|
||||||
|
final ThemeData theme;
|
||||||
|
|
||||||
|
final String? suffix;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 200);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get barrierDismissible => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String? barrierLabel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool didPop(T? result) {
|
||||||
|
if (onCancel != null) {
|
||||||
|
if (result == null) {
|
||||||
|
onCancel!(false);
|
||||||
|
} else if (!(result as bool)) {
|
||||||
|
onCancel!(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color get barrierColor => Colors.black54;
|
||||||
|
|
||||||
|
late AnimationController _animationController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
AnimationController createAnimationController() {
|
||||||
|
_animationController =
|
||||||
|
BottomSheet.createAnimationController(navigator!.overlay!);
|
||||||
|
return _animationController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
List mData = [];
|
||||||
|
// 初始化数据
|
||||||
|
if (data is PickerDataType) {
|
||||||
|
mData = pickerData[data]!;
|
||||||
|
} else if (data is List) {
|
||||||
|
mData.addAll(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget bottomSheet = MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeTop: true,
|
||||||
|
child: _PickerContentView(
|
||||||
|
data: mData,
|
||||||
|
selectData: selectData,
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
route: this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
bottomSheet = Theme(data: theme, child: bottomSheet);
|
||||||
|
|
||||||
|
return bottomSheet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerContentView extends StatefulWidget {
|
||||||
|
_PickerContentView({
|
||||||
|
Key? key,
|
||||||
|
required this.data,
|
||||||
|
this.selectData,
|
||||||
|
required this.pickerStyle,
|
||||||
|
required this.route,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final List data;
|
||||||
|
final dynamic selectData;
|
||||||
|
final SinglePickerRoute route;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() =>
|
||||||
|
_PickerState(this.data, this.selectData, this.pickerStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerState extends State<_PickerContentView> {
|
||||||
|
final PickerStyle _pickerStyle;
|
||||||
|
|
||||||
|
// 选中数据
|
||||||
|
var _selectData;
|
||||||
|
|
||||||
|
// 选中数据下标
|
||||||
|
int _selectPosition = 0;
|
||||||
|
|
||||||
|
List _data = [];
|
||||||
|
|
||||||
|
late FixedExtentScrollController scrollCtrl;
|
||||||
|
|
||||||
|
// 单位widget Padding left
|
||||||
|
late double _laberLeft;
|
||||||
|
|
||||||
|
_PickerState(this._data, this._selectData, this._pickerStyle) {
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
scrollCtrl.dispose();
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: AnimatedBuilder(
|
||||||
|
animation: widget.route.animation!,
|
||||||
|
builder: (BuildContext context, Widget? child) {
|
||||||
|
return ClipRect(
|
||||||
|
child: CustomSingleChildLayout(
|
||||||
|
delegate: _BottomPickerLayout(widget.route.animation!.value,
|
||||||
|
pickerStyle: _pickerStyle),
|
||||||
|
child: GestureDetector(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: _renderPickerView(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
int pindex = 0;
|
||||||
|
pindex = _data
|
||||||
|
.indexWhere((element) => element.toString() == _selectData.toString());
|
||||||
|
// 如果没有匹配到选择器对应数据,我们得修改选择器选中数据 ,不然confirm 返回的事设置的数据
|
||||||
|
if (pindex < 0) {
|
||||||
|
_selectData = _data[0];
|
||||||
|
pindex = 0;
|
||||||
|
}
|
||||||
|
_selectPosition = pindex;
|
||||||
|
|
||||||
|
scrollCtrl = new FixedExtentScrollController(initialItem: pindex);
|
||||||
|
_laberLeft = _pickerLaberPadding(_data[pindex].toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setPicker(int index) {
|
||||||
|
var selectedProvince = _data[index];
|
||||||
|
|
||||||
|
// if (_selectData.toString() != selectedProvince.toString()) {
|
||||||
|
// setState(() {
|
||||||
|
// });
|
||||||
|
_selectData = selectedProvince;
|
||||||
|
_selectPosition = index;
|
||||||
|
|
||||||
|
_notifyLocationChanged();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void _notifyLocationChanged() {
|
||||||
|
if (widget.route.onChanged != null) {
|
||||||
|
widget.route.onChanged!(_selectData, _selectPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double _pickerLaberPadding(String? text) {
|
||||||
|
double left = 60;
|
||||||
|
|
||||||
|
if (text != null) {
|
||||||
|
left = left + text.length * 12;
|
||||||
|
}
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 动态计算itemTextSize
|
||||||
|
double _pickerFontSize(String text) {
|
||||||
|
if (text.length <= 6) {
|
||||||
|
return 18.0;
|
||||||
|
} else if (text.length < 9) {
|
||||||
|
return 16.0;
|
||||||
|
} else if (text.length < 13) {
|
||||||
|
return 12.0;
|
||||||
|
} else {
|
||||||
|
return 10.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderPickerView() {
|
||||||
|
Widget itemView = _renderItemView();
|
||||||
|
|
||||||
|
if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) {
|
||||||
|
return itemView;
|
||||||
|
}
|
||||||
|
List<Widget> viewList = <Widget>[];
|
||||||
|
if (_pickerStyle.showTitleBar) {
|
||||||
|
viewList.add(_titleView());
|
||||||
|
}
|
||||||
|
if (_pickerStyle.menu != null) {
|
||||||
|
viewList.add(_pickerStyle.menu!);
|
||||||
|
}
|
||||||
|
viewList.add(itemView);
|
||||||
|
|
||||||
|
return Column(children: viewList);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderItemView() {
|
||||||
|
// 选择器
|
||||||
|
Widget cPicker = CupertinoPicker.builder(
|
||||||
|
scrollController: scrollCtrl,
|
||||||
|
itemExtent: _pickerStyle.pickerItemHeight,
|
||||||
|
selectionOverlay: _pickerStyle.itemOverlay,
|
||||||
|
onSelectedItemChanged: (int index) {
|
||||||
|
_setPicker(index);
|
||||||
|
if (widget.route.suffix != null && widget.route.suffix != '') {
|
||||||
|
// 如果设置了才计算 单位的paddingLeft
|
||||||
|
double resuleLeft = _pickerLaberPadding(_data[index].toString());
|
||||||
|
if (resuleLeft != _laberLeft) {
|
||||||
|
setState(() {
|
||||||
|
_laberLeft = resuleLeft;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
childCount: _data.length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
String text = _data[index].toString();
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(text,
|
||||||
|
style: TextStyle(
|
||||||
|
color: _pickerStyle.textColor,
|
||||||
|
fontSize: _pickerStyle.textSize ?? _pickerFontSize(text),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget view;
|
||||||
|
// 单位
|
||||||
|
if (widget.route.suffix != null && widget.route.suffix != '') {
|
||||||
|
Widget laberView = Center(
|
||||||
|
child: AnimatedPadding(
|
||||||
|
duration: Duration(milliseconds: 100),
|
||||||
|
padding: EdgeInsets.only(left: _laberLeft),
|
||||||
|
child: Text(widget.route.suffix!,
|
||||||
|
style: TextStyle(
|
||||||
|
color: _pickerStyle.textColor,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500)),
|
||||||
|
));
|
||||||
|
|
||||||
|
view = Stack(children: [cPicker, laberView]);
|
||||||
|
} else {
|
||||||
|
view = cPicker;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 40),
|
||||||
|
height: _pickerStyle.pickerHeight,
|
||||||
|
color: _pickerStyle.backgroundColor,
|
||||||
|
child: view,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择器上面的view
|
||||||
|
Widget _titleView() {
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerTitleHeight,
|
||||||
|
decoration: _pickerStyle.headDecoration,
|
||||||
|
child: Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
/// 取消按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () => Navigator.pop(context, false),
|
||||||
|
child: _pickerStyle.cancelButton),
|
||||||
|
|
||||||
|
/// 标题
|
||||||
|
Expanded(child: _pickerStyle.title),
|
||||||
|
|
||||||
|
/// 确认按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.route.onConfirm != null) {
|
||||||
|
print('longer _selectPosition >>> ${_selectPosition}');
|
||||||
|
widget.route.onConfirm!(_selectData, _selectPosition);
|
||||||
|
}
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
child: _pickerStyle.commitButton)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BottomPickerLayout extends SingleChildLayoutDelegate {
|
||||||
|
_BottomPickerLayout(this.progress, {required this.pickerStyle});
|
||||||
|
|
||||||
|
final double progress;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
||||||
|
double maxHeight = pickerStyle.pickerHeight;
|
||||||
|
if (pickerStyle.showTitleBar) {
|
||||||
|
maxHeight += pickerStyle.pickerTitleHeight;
|
||||||
|
}
|
||||||
|
if (pickerStyle.menu != null) {
|
||||||
|
maxHeight += pickerStyle.menuHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoxConstraints(
|
||||||
|
minWidth: constraints.maxWidth,
|
||||||
|
maxWidth: constraints.maxWidth,
|
||||||
|
minHeight: 0.0,
|
||||||
|
maxHeight: maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Offset getPositionForChild(Size size, Size childSize) {
|
||||||
|
double height = size.height - childSize.height * progress;
|
||||||
|
return Offset(0.0, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRelayout(_BottomPickerLayout oldDelegate) {
|
||||||
|
return progress != oldDelegate.progress;
|
||||||
|
}
|
||||||
|
}
|
||||||
252
star_lock/lib/tools/pickers/pickers.dart
Normal file
252
star_lock/lib/tools/pickers/pickers.dart
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/address_picker/route/address_picker_route.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/more_pickers/init_data.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/more_pickers/route/multiple_link_picker_route.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/more_pickers/route/multiple_picker_route.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/more_pickers/route/single_picker_route.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/default_style.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/picker_style.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/pduration.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/suffix.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/route/date_picker_route.dart';
|
||||||
|
// import 'package:flutter_pickers/address_picker/route/address_picker_route.dart';
|
||||||
|
// import 'package:flutter_pickers/more_pickers/init_data.dart';
|
||||||
|
// import 'package:flutter_pickers/more_pickers/route/multiple_link_picker_route.dart';
|
||||||
|
// import 'package:flutter_pickers/more_pickers/route/multiple_picker_route.dart';
|
||||||
|
// import 'package:flutter_pickers/more_pickers/route/single_picker_route.dart';
|
||||||
|
// import 'package:flutter_pickers/style/default_style.dart';
|
||||||
|
// import 'package:flutter_pickers/style/picker_style.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/pduration.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/suffix.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/route/date_picker_route.dart';
|
||||||
|
|
||||||
|
import 'time_picker/model/date_item_model.dart';
|
||||||
|
|
||||||
|
/// [onChanged] 选择器发生变动
|
||||||
|
/// [onConfirm] 选择器提交
|
||||||
|
/// [pickerStyle] 样式
|
||||||
|
/// [suffix] 后缀
|
||||||
|
class Pickers {
|
||||||
|
/// 单列 通用选择器
|
||||||
|
static void showSinglePicker(BuildContext context,
|
||||||
|
{required dynamic data,
|
||||||
|
dynamic selectData,
|
||||||
|
String? suffix,
|
||||||
|
PickerStyle? pickerStyle,
|
||||||
|
SingleCallback? onChanged,
|
||||||
|
SingleCallback? onConfirm,
|
||||||
|
Function(bool isCancel)? onCancel,
|
||||||
|
bool overlapTabBar = false}) {
|
||||||
|
assert((data is List) || (data is PickerDataType),
|
||||||
|
'params : data must List or PickerDataType');
|
||||||
|
|
||||||
|
if (pickerStyle == null) {
|
||||||
|
pickerStyle = DefaultPickerStyle();
|
||||||
|
}
|
||||||
|
if (pickerStyle.context == null) {
|
||||||
|
pickerStyle.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.of(context, rootNavigator: overlapTabBar).push(SinglePickerRoute(
|
||||||
|
data: data,
|
||||||
|
suffix: suffix,
|
||||||
|
selectData: selectData,
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
onChanged: onChanged,
|
||||||
|
onConfirm: onConfirm,
|
||||||
|
onCancel: onCancel,
|
||||||
|
// theme: Theme.of(context, shadowThemeOnly: true),
|
||||||
|
theme: Theme.of(context),
|
||||||
|
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 通用 多列选择器
|
||||||
|
/// 无关联
|
||||||
|
static void showMultiPicker(BuildContext context,
|
||||||
|
{required List<List> data,
|
||||||
|
List? selectData,
|
||||||
|
List? suffix,
|
||||||
|
PickerStyle? pickerStyle,
|
||||||
|
MultipleCallback? onChanged,
|
||||||
|
MultipleCallback? onConfirm,
|
||||||
|
Function(bool isCancel)? onCancel,
|
||||||
|
bool overlapTabBar = false}) {
|
||||||
|
if (selectData == null) {
|
||||||
|
selectData = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pickerStyle == null) {
|
||||||
|
pickerStyle = DefaultPickerStyle();
|
||||||
|
}
|
||||||
|
if (pickerStyle.context == null) {
|
||||||
|
pickerStyle.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.of(context, rootNavigator: overlapTabBar)
|
||||||
|
.push(MultiplePickerRoute(
|
||||||
|
data: data,
|
||||||
|
selectData: selectData,
|
||||||
|
suffix: suffix,
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
onChanged: onChanged,
|
||||||
|
onConfirm: onConfirm,
|
||||||
|
onCancel: onCancel,
|
||||||
|
// theme: Theme.of(context, shadowThemeOnly: true),
|
||||||
|
theme: Theme.of(context),
|
||||||
|
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 通用 多列选择器
|
||||||
|
/// 有关联
|
||||||
|
/// [columeNum] 最大的列数
|
||||||
|
static void showMultiLinkPicker(BuildContext context,
|
||||||
|
{required dynamic data,
|
||||||
|
required int columeNum,
|
||||||
|
List? selectData,
|
||||||
|
List? suffix,
|
||||||
|
PickerStyle? pickerStyle,
|
||||||
|
MultipleLinkCallback? onChanged,
|
||||||
|
MultipleLinkCallback? onConfirm,
|
||||||
|
Function(bool isCancel)? onCancel,
|
||||||
|
bool overlapTabBar = false}) {
|
||||||
|
assert(data is Map, 'params : data must Map');
|
||||||
|
|
||||||
|
if (selectData == null) {
|
||||||
|
selectData = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pickerStyle == null) {
|
||||||
|
pickerStyle = DefaultPickerStyle();
|
||||||
|
}
|
||||||
|
if (pickerStyle.context == null) {
|
||||||
|
pickerStyle.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.of(context, rootNavigator: overlapTabBar)
|
||||||
|
.push(MultipleLinkPickerRoute(
|
||||||
|
data: data,
|
||||||
|
selectData: selectData,
|
||||||
|
columeNum: columeNum,
|
||||||
|
suffix: suffix,
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
onChanged: onChanged,
|
||||||
|
onConfirm: onConfirm,
|
||||||
|
onCancel: onCancel,
|
||||||
|
// theme: Theme.of(context, shadowThemeOnly: true),
|
||||||
|
theme: Theme.of(context),
|
||||||
|
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 自定义 地区选择器
|
||||||
|
/// [initProvince] 初始化 省
|
||||||
|
/// [initCity] 初始化 市
|
||||||
|
/// [initTown] 初始化 区
|
||||||
|
/// [onChanged] 选择器发生变动
|
||||||
|
/// [onConfirm] 选择器提交
|
||||||
|
/// [addAllItem] 市、区是否添加 '全部' 选项 默认:true
|
||||||
|
static void showAddressPicker(BuildContext context,
|
||||||
|
{PickerStyle? pickerStyle,
|
||||||
|
String initProvince: '',
|
||||||
|
String initCity: '',
|
||||||
|
String? initTown,
|
||||||
|
bool addAllItem: true,
|
||||||
|
AddressCallback? onChanged,
|
||||||
|
AddressCallback? onConfirm,
|
||||||
|
Function(bool isCancel)? onCancel,
|
||||||
|
bool overlapTabBar = false}) {
|
||||||
|
if (pickerStyle == null) {
|
||||||
|
pickerStyle = DefaultPickerStyle();
|
||||||
|
}
|
||||||
|
if (pickerStyle.context == null) {
|
||||||
|
pickerStyle.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.of(context, rootNavigator: overlapTabBar).push(AddressPickerRoute(
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
initProvince: initProvince,
|
||||||
|
initCity: initCity,
|
||||||
|
initTown: initTown,
|
||||||
|
onChanged: onChanged,
|
||||||
|
onConfirm: onConfirm,
|
||||||
|
onCancel: onCancel,
|
||||||
|
addAllItem: addAllItem,
|
||||||
|
theme: Theme.of(context),
|
||||||
|
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 时间选择器
|
||||||
|
/// [Suffix] : 每列时间对应的单位 默认:中文常规 Suffix(years: '年',month: '月');
|
||||||
|
/// [selectDate] : 初始化选中时间 默认现在
|
||||||
|
/// PDuration.now();
|
||||||
|
/// PDuration.parse(DateTime.parse('20210139'));
|
||||||
|
/// PDuration(year: 2020,month: 2);
|
||||||
|
/// [maxDate] : 最大时间 用法同上
|
||||||
|
/// tip: 当只有单列数据,该限制不产生关联 只针对单列item限制,比如 maxDate>day = 3 minDate>day = 10,那么所有的月份都只显示3-10之间
|
||||||
|
/// [minDate] : 最小时间 用法同上
|
||||||
|
/// [mode] : 时间选择器所显示样式 16 种时间样式 默认:DateMode.YMD
|
||||||
|
static void showDatePicker(BuildContext context,
|
||||||
|
{DateMode mode: DateMode.YMD,
|
||||||
|
PDuration? selectDate,
|
||||||
|
PDuration? maxDate,
|
||||||
|
PDuration? minDate,
|
||||||
|
Suffix? suffix,
|
||||||
|
PickerStyle? pickerStyle,
|
||||||
|
DateCallback? onChanged,
|
||||||
|
DateCallback? onConfirm,
|
||||||
|
Function(bool isCancel)? onCancel,
|
||||||
|
bool overlapTabBar = false}) {
|
||||||
|
if (pickerStyle == null) {
|
||||||
|
pickerStyle = DefaultPickerStyle();
|
||||||
|
}
|
||||||
|
if (pickerStyle.context == null) {
|
||||||
|
pickerStyle.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectDate == null) selectDate = PDuration.now();
|
||||||
|
if (suffix == null) suffix = Suffix.normal();
|
||||||
|
|
||||||
|
// 解析是否有对应数据
|
||||||
|
DateItemModel dateItemModel = DateItemModel.parse(mode);
|
||||||
|
|
||||||
|
if (maxDate == null) maxDate = PDuration(year: 2100);
|
||||||
|
if (minDate == null) minDate = PDuration(year: 1900);
|
||||||
|
|
||||||
|
if ((dateItemModel.day || dateItemModel.year)) {
|
||||||
|
if (intEmpty(selectDate.year)) {
|
||||||
|
print('picker Tip >>> initDate未设置years,默认设置为now().year');
|
||||||
|
selectDate.year = DateTime.now().year;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 如果有年item ,必须限制
|
||||||
|
if (intEmpty(maxDate.year)) maxDate.year = 2100;
|
||||||
|
if (intEmpty(minDate.year)) minDate.year = 1900;
|
||||||
|
|
||||||
|
// print('longer >>> ${minDate.year}');
|
||||||
|
|
||||||
|
if (dateItemModel.month || dateItemModel.day) {
|
||||||
|
assert(minDate.year! > 1582, 'min Date Year must > 1582');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.of(context, rootNavigator: overlapTabBar).push(DatePickerRoute(
|
||||||
|
mode: mode,
|
||||||
|
initDate: selectDate,
|
||||||
|
maxDate: maxDate,
|
||||||
|
minDate: minDate,
|
||||||
|
suffix: suffix,
|
||||||
|
pickerStyle: pickerStyle,
|
||||||
|
onChanged: onChanged,
|
||||||
|
onConfirm: onConfirm,
|
||||||
|
onCancel: onCancel,
|
||||||
|
// theme: Theme.of(context, shadowThemeOnly: true),
|
||||||
|
theme: Theme.of(context),
|
||||||
|
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
205
star_lock/lib/tools/pickers/style/default_style.dart
Normal file
205
star_lock/lib/tools/pickers/style/default_style.dart
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/picker_style.dart';
|
||||||
|
// import 'package:flutter_pickers/style/picker_style.dart';
|
||||||
|
|
||||||
|
// 日间圆角
|
||||||
|
const headDecorationLight = BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10), topRight: Radius.circular(10)));
|
||||||
|
|
||||||
|
/// 无标题样式
|
||||||
|
class NoTitleStyle extends PickerStyle {
|
||||||
|
NoTitleStyle() {
|
||||||
|
showTitleBar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 夜间
|
||||||
|
NoTitleStyle.dark() {
|
||||||
|
showTitleBar = false;
|
||||||
|
backgroundColor = Colors.grey[800]!;
|
||||||
|
textColor = Colors.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 默认样式
|
||||||
|
class DefaultPickerStyle extends PickerStyle {
|
||||||
|
DefaultPickerStyle({bool haveRadius = false, String? title}) {
|
||||||
|
if (haveRadius) {
|
||||||
|
headDecoration = const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10), topRight: Radius.circular(10)));
|
||||||
|
}
|
||||||
|
if (title != null && title != '') {
|
||||||
|
this.title = Center(
|
||||||
|
child: Text(title,
|
||||||
|
style: const TextStyle(color: Colors.grey, fontSize: 14)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 夜间
|
||||||
|
DefaultPickerStyle.dark({bool haveRadius = false, String? title}) {
|
||||||
|
commitButton = Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: const EdgeInsets.only(left: 12, right: 22),
|
||||||
|
child: const Text('确定',
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 16.0)),
|
||||||
|
);
|
||||||
|
|
||||||
|
cancelButton = Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: const EdgeInsets.only(left: 22, right: 12),
|
||||||
|
child: const Text('取消',
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 16.0)),
|
||||||
|
);
|
||||||
|
|
||||||
|
headDecoration = BoxDecoration(
|
||||||
|
color: Colors.grey[800],
|
||||||
|
borderRadius: !haveRadius
|
||||||
|
? null
|
||||||
|
: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10), topRight: Radius.circular(10)));
|
||||||
|
|
||||||
|
if (title != null && title != '') {
|
||||||
|
this.title = Center(
|
||||||
|
child: Text(title,
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 14)));
|
||||||
|
}
|
||||||
|
|
||||||
|
backgroundColor = Colors.grey[800]!;
|
||||||
|
textColor = Colors.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 关闭按钮样式
|
||||||
|
class ClosePickerStyle extends PickerStyle {
|
||||||
|
/// 日间
|
||||||
|
ClosePickerStyle({bool haveRadius = false, String? title}) {
|
||||||
|
if (haveRadius) {
|
||||||
|
headDecoration = const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10), topRight: Radius.circular(10)));
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelButton = const SizedBox();
|
||||||
|
if (title != null && title != '') {
|
||||||
|
this.title = Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 16),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(title,
|
||||||
|
style: const TextStyle(color: Colors.grey, fontSize: 14))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
commitButton = Container(
|
||||||
|
// padding: const EdgeInsets.all(4),
|
||||||
|
margin: const EdgeInsets.only(right: 12),
|
||||||
|
child: const Icon(Icons.close, color: Colors.grey, size: 28),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 夜间
|
||||||
|
ClosePickerStyle.dark({bool haveRadius = false, String? title}) {
|
||||||
|
headDecoration = BoxDecoration(
|
||||||
|
color: Colors.grey[800],
|
||||||
|
borderRadius: !haveRadius
|
||||||
|
? null
|
||||||
|
: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10), topRight: Radius.circular(10)));
|
||||||
|
|
||||||
|
cancelButton = const SizedBox();
|
||||||
|
commitButton = Container(
|
||||||
|
margin: const EdgeInsets.only(right: 12),
|
||||||
|
child: const Icon(Icons.close, color: Colors.white, size: 28),
|
||||||
|
);
|
||||||
|
if (title != null && title != '') {
|
||||||
|
this.title = Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 16),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(title,
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 14))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
backgroundColor = Colors.grey[800]!;
|
||||||
|
textColor = Colors.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 圆角按钮样式
|
||||||
|
class RaisedPickerStyle extends PickerStyle {
|
||||||
|
RaisedPickerStyle(
|
||||||
|
{bool haveRadius = false, String? title, Color color = Colors.blue}) {
|
||||||
|
if (haveRadius) {
|
||||||
|
headDecoration = const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10), topRight: Radius.circular(10)));
|
||||||
|
}
|
||||||
|
commitButton = Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
|
||||||
|
margin: const EdgeInsets.only(right: 22),
|
||||||
|
decoration:
|
||||||
|
BoxDecoration(color: color, borderRadius: BorderRadius.circular(4)),
|
||||||
|
child: const Text('确定',
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 15.0)),
|
||||||
|
);
|
||||||
|
|
||||||
|
cancelButton = Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
|
||||||
|
margin: const EdgeInsets.only(left: 22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: color, width: 1),
|
||||||
|
borderRadius: BorderRadius.circular(4)),
|
||||||
|
child: Text('取消', style: TextStyle(color: color, fontSize: 15.0)),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (title != null && title != '') {
|
||||||
|
this.title = Center(
|
||||||
|
child: Text(title,
|
||||||
|
style: const TextStyle(color: Colors.grey, fontSize: 14)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 夜间
|
||||||
|
RaisedPickerStyle.dark(
|
||||||
|
{bool haveRadius = false, String? title, Color? color}) {
|
||||||
|
headDecoration = BoxDecoration(
|
||||||
|
color: Colors.grey[800],
|
||||||
|
borderRadius: !haveRadius
|
||||||
|
? null
|
||||||
|
: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10), topRight: Radius.circular(10)));
|
||||||
|
|
||||||
|
commitButton = Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
|
||||||
|
margin: const EdgeInsets.only(right: 22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color ?? Colors.blue, borderRadius: BorderRadius.circular(4)),
|
||||||
|
child: const Text('确定',
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 15.0)),
|
||||||
|
);
|
||||||
|
|
||||||
|
cancelButton = Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
|
||||||
|
margin: const EdgeInsets.only(left: 22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: Colors.white, width: 1),
|
||||||
|
borderRadius: BorderRadius.circular(4)),
|
||||||
|
child: const Text('取消',
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 15.0)),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (title != null && title != '') {
|
||||||
|
this.title = Center(
|
||||||
|
child: Text(title,
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 14)));
|
||||||
|
}
|
||||||
|
|
||||||
|
backgroundColor = Colors.grey[800]!;
|
||||||
|
textColor = Colors.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
186
star_lock/lib/tools/pickers/style/picker_style.dart
Normal file
186
star_lock/lib/tools/pickers/style/picker_style.dart
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// 基础样式
|
||||||
|
/// [showTitleBar] 是否显示头部(选择器以上的控件) 默认:true
|
||||||
|
/// [menu] 头部和选择器之间的菜单widget,默认null 不显示
|
||||||
|
/// [title] 头部 中间的标题 默认SizedBox() 不显示
|
||||||
|
/// [pickerHeight] 选择器下面 picker 的整体高度 固定高度:220.0
|
||||||
|
/// [pickerTitleHeight] 选择器上面 title 确认、取消的整体高度 固定高度:44.0
|
||||||
|
/// [pickerItemHeight] 选择器每个被选中item的高度:40.0
|
||||||
|
/// [menuHeight] 头部和选择器之间的菜单高度 固定高度:36.0
|
||||||
|
/// [cancelButton] 头部的取消按钮
|
||||||
|
/// [commitButton] 头部的确认按钮
|
||||||
|
/// [textColor] 选择器的文字颜色 默认黑色
|
||||||
|
/// [textSize] 选择器的文字大小
|
||||||
|
/// [backgroundColor] 选择器的背景颜色 默认白色
|
||||||
|
/// [headDecoration] 头部Container 的Decoration 默认:BoxDecoration(color: Colors.white)
|
||||||
|
///
|
||||||
|
class PickerStyle {
|
||||||
|
BuildContext? _context;
|
||||||
|
|
||||||
|
bool? _showTitleBar;
|
||||||
|
Widget? _menu;
|
||||||
|
double? _pickerHeight;
|
||||||
|
double? _pickerTitleHeight;
|
||||||
|
double? _pickerItemHeight;
|
||||||
|
double? _menuHeight;
|
||||||
|
|
||||||
|
Widget? _cancelButton;
|
||||||
|
Widget? _commitButton;
|
||||||
|
Widget? _title;
|
||||||
|
Decoration? _headDecoration;
|
||||||
|
Color? _backgroundColor;
|
||||||
|
Color? _textColor;
|
||||||
|
double? _textSize;
|
||||||
|
Widget? _itemOverlay;
|
||||||
|
|
||||||
|
PickerStyle({
|
||||||
|
BuildContext? context,
|
||||||
|
bool? showTitleBar,
|
||||||
|
Widget? menu,
|
||||||
|
double? pickerHeight,
|
||||||
|
double? pickerTitleHeight,
|
||||||
|
double? pickerItemHeight,
|
||||||
|
double? menuHeight,
|
||||||
|
Widget? cancelButton,
|
||||||
|
Widget? commitButton,
|
||||||
|
Widget? title,
|
||||||
|
Decoration? headDecoration,
|
||||||
|
Color? backgroundColor,
|
||||||
|
Color? textColor,
|
||||||
|
double? textSize,
|
||||||
|
Widget? itemOverlay,
|
||||||
|
}) {
|
||||||
|
this._context = context;
|
||||||
|
this._showTitleBar = showTitleBar;
|
||||||
|
this._menu = menu;
|
||||||
|
|
||||||
|
this._pickerHeight = pickerHeight;
|
||||||
|
this._pickerTitleHeight = pickerTitleHeight;
|
||||||
|
this._pickerItemHeight = pickerItemHeight;
|
||||||
|
this._menuHeight = menuHeight;
|
||||||
|
|
||||||
|
this._cancelButton = cancelButton;
|
||||||
|
this._commitButton = commitButton;
|
||||||
|
this._title = title;
|
||||||
|
this._headDecoration = headDecoration;
|
||||||
|
this._backgroundColor = backgroundColor;
|
||||||
|
this._textColor = textColor;
|
||||||
|
this._textSize = textSize;
|
||||||
|
this._itemOverlay = itemOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
set context(BuildContext? value) {
|
||||||
|
_context = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set menuHeight(double value) {
|
||||||
|
_menuHeight = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set menu(Widget? value) {
|
||||||
|
_menu = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set pickerHeight(double value) {
|
||||||
|
_pickerHeight = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set pickerTitleHeight(double value) {
|
||||||
|
_pickerTitleHeight = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set pickerItemHeight(double value) {
|
||||||
|
_pickerItemHeight = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set cancelButton(Widget value) {
|
||||||
|
_cancelButton = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set commitButton(Widget value) {
|
||||||
|
_commitButton = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set itemOverlay(Widget? value) {
|
||||||
|
_itemOverlay = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set title(Widget value) {
|
||||||
|
_title = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set headDecoration(Decoration value) {
|
||||||
|
_headDecoration = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set backgroundColor(Color value) {
|
||||||
|
_backgroundColor = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set textColor(Color value) {
|
||||||
|
_textColor = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set textSize(double? value) {
|
||||||
|
_textSize = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set showTitleBar(bool value) {
|
||||||
|
_showTitleBar = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildContext? get context => this._context;
|
||||||
|
|
||||||
|
/// 选择器背景色 默认白色
|
||||||
|
Color get backgroundColor => this._backgroundColor ?? Colors.white;
|
||||||
|
|
||||||
|
Decoration get headDecoration =>
|
||||||
|
this._headDecoration ?? BoxDecoration(color: Colors.white);
|
||||||
|
|
||||||
|
Widget? get menu => this._menu;
|
||||||
|
|
||||||
|
double get menuHeight => this._menuHeight ?? 36.0;
|
||||||
|
|
||||||
|
double get pickerHeight => this._pickerHeight ?? 220.0;
|
||||||
|
|
||||||
|
double get pickerItemHeight => this._pickerItemHeight ?? 40.0;
|
||||||
|
|
||||||
|
double get pickerTitleHeight => this._pickerTitleHeight ?? 44.0;
|
||||||
|
|
||||||
|
bool get showTitleBar => this._showTitleBar ?? true;
|
||||||
|
|
||||||
|
Color get textColor => this._textColor ?? Colors.black87;
|
||||||
|
|
||||||
|
double? get textSize => this._textSize;
|
||||||
|
|
||||||
|
Widget get title => this._title ?? SizedBox();
|
||||||
|
|
||||||
|
Widget get commitButton => getCommitButton();
|
||||||
|
|
||||||
|
Widget get cancelButton => getCancelButton();
|
||||||
|
|
||||||
|
Widget? get itemOverlay => this._itemOverlay;
|
||||||
|
|
||||||
|
Widget getCommitButton() {
|
||||||
|
return this._commitButton ??
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: const EdgeInsets.only(left: 12, right: 22),
|
||||||
|
child: const Text('确定',
|
||||||
|
style: TextStyle(color: Colors.blue, fontSize: 16.0)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget getCancelButton() {
|
||||||
|
return this._cancelButton ??
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: const EdgeInsets.only(left: 22, right: 12),
|
||||||
|
child: Text('取消',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context!).unselectedWidgetColor,
|
||||||
|
fontSize: 16.0)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
// 是否需要 显示/设置 对应的选项
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
|
||||||
|
class DateItemModel {
|
||||||
|
late bool year;
|
||||||
|
late bool month;
|
||||||
|
late bool day;
|
||||||
|
late bool hour;
|
||||||
|
late bool minute;
|
||||||
|
late bool second;
|
||||||
|
|
||||||
|
DateItemModel(
|
||||||
|
this.year, this.month, this.day, this.hour, this.minute, this.second);
|
||||||
|
|
||||||
|
DateItemModel.parse(DateMode dateMode) {
|
||||||
|
this.year = DateModeMap[dateMode]!.contains('年');
|
||||||
|
this.month = DateModeMap[dateMode]!.contains('月');
|
||||||
|
this.day = DateModeMap[dateMode]!.contains('日');
|
||||||
|
this.hour = DateModeMap[dateMode]!.contains('时');
|
||||||
|
this.minute = DateModeMap[dateMode]!.contains('分');
|
||||||
|
this.second = DateModeMap[dateMode]!.contains('秒');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回需要显示多少个picker
|
||||||
|
int get length {
|
||||||
|
int i = 0;
|
||||||
|
if (this.year) ++i;
|
||||||
|
if (this.month) ++i;
|
||||||
|
if (this.day) ++i;
|
||||||
|
if (this.hour) ++i;
|
||||||
|
if (this.minute) ++i;
|
||||||
|
if (this.second) ++i;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const DateModeMap = {
|
||||||
|
DateMode.YMDHMS: "年月日时分秒",
|
||||||
|
DateMode.YMDHM: '年月日时分',
|
||||||
|
DateMode.YMDH: '年月日时',
|
||||||
|
DateMode.YMD: '年月日',
|
||||||
|
DateMode.YM: '年月',
|
||||||
|
DateMode.Y: '年',
|
||||||
|
DateMode.MDHMS: '月日时分秒',
|
||||||
|
DateMode.MDHM: '月日时分',
|
||||||
|
DateMode.MDH: '月日时',
|
||||||
|
DateMode.MD: '月日',
|
||||||
|
DateMode.HMS: '时分秒',
|
||||||
|
DateMode.HM: '时分',
|
||||||
|
DateMode.MS: '分秒',
|
||||||
|
DateMode.S: '秒',
|
||||||
|
DateMode.M: '月',
|
||||||
|
DateMode.H: '时'
|
||||||
|
};
|
||||||
53
star_lock/lib/tools/pickers/time_picker/model/date_mode.dart
Normal file
53
star_lock/lib/tools/pickers/time_picker/model/date_mode.dart
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/// 时间选择器 所显示样式
|
||||||
|
/// 16 种时间样式
|
||||||
|
///
|
||||||
|
enum DateMode {
|
||||||
|
/// 【yyyy-MM-dd HH:mm:ss】年月日时分秒
|
||||||
|
YMDHMS,
|
||||||
|
|
||||||
|
/// 【yyyy-MM-dd HH:mm】年月日时分
|
||||||
|
YMDHM,
|
||||||
|
|
||||||
|
/// 【yyyy-MM-dd HH】年月日时
|
||||||
|
YMDH,
|
||||||
|
|
||||||
|
/// 【yyyy-MM-dd】年月日
|
||||||
|
YMD,
|
||||||
|
|
||||||
|
/// 【yyyy-MM】年月
|
||||||
|
YM,
|
||||||
|
|
||||||
|
/// 【yyyy】年
|
||||||
|
Y,
|
||||||
|
|
||||||
|
/// 【MM-dd HH:mm:ss】月日时分秒
|
||||||
|
MDHMS,
|
||||||
|
|
||||||
|
/// 【MM-dd HH:mm】月日时分
|
||||||
|
MDHM,
|
||||||
|
|
||||||
|
/// 【MM-dd HH:mm】月日时
|
||||||
|
MDH,
|
||||||
|
|
||||||
|
/// 【MM-dd】月日
|
||||||
|
MD,
|
||||||
|
|
||||||
|
/// 【HH:mm:ss】时分秒
|
||||||
|
HMS,
|
||||||
|
|
||||||
|
/// 【HH:mm】时分
|
||||||
|
HM,
|
||||||
|
|
||||||
|
/// 【mm:ss】分秒
|
||||||
|
MS,
|
||||||
|
|
||||||
|
/// 【ss】秒
|
||||||
|
S,
|
||||||
|
|
||||||
|
/// 【MM】月
|
||||||
|
M,
|
||||||
|
|
||||||
|
/// 【HH】时
|
||||||
|
H,
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
// import 'package:flutter_pickers/time_picker/model/date_type.dart';
|
||||||
|
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_type.dart';
|
||||||
|
|
||||||
|
/// 时间选择器 item 生成的对应数据
|
||||||
|
class DateTimeData {
|
||||||
|
List _year = [];
|
||||||
|
List _month = [];
|
||||||
|
List _day = [];
|
||||||
|
List _hour = [];
|
||||||
|
List _minute = [];
|
||||||
|
List _second = [];
|
||||||
|
|
||||||
|
List getListByName(DateType type) {
|
||||||
|
switch (type) {
|
||||||
|
case DateType.Year:
|
||||||
|
return year;
|
||||||
|
case DateType.Month:
|
||||||
|
return month;
|
||||||
|
case DateType.Day:
|
||||||
|
return day;
|
||||||
|
case DateType.Hour:
|
||||||
|
return hour;
|
||||||
|
case DateType.Minute:
|
||||||
|
return minute;
|
||||||
|
case DateType.Second:
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List get year => _year;
|
||||||
|
|
||||||
|
set year(List value) {
|
||||||
|
_year.clear();
|
||||||
|
_year.addAll(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
List get month => _month;
|
||||||
|
|
||||||
|
set month(List value) {
|
||||||
|
_month.clear();
|
||||||
|
_month.addAll(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
List get second => _second;
|
||||||
|
|
||||||
|
set second(List value) {
|
||||||
|
_second.clear();
|
||||||
|
_second.addAll(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
List get minute => _minute;
|
||||||
|
|
||||||
|
set minute(List value) {
|
||||||
|
_minute.clear();
|
||||||
|
_minute.addAll(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
List get hour => _hour;
|
||||||
|
|
||||||
|
set hour(List value) {
|
||||||
|
_hour.clear();
|
||||||
|
_hour.addAll(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
List get day => _day;
|
||||||
|
|
||||||
|
set day(List value) {
|
||||||
|
_day.clear();
|
||||||
|
_day.addAll(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
star_lock/lib/tools/pickers/time_picker/model/date_type.dart
Normal file
10
star_lock/lib/tools/pickers/time_picker/model/date_type.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
enum DateType{
|
||||||
|
Year,
|
||||||
|
Month,
|
||||||
|
Day,
|
||||||
|
Hour,
|
||||||
|
Minute,
|
||||||
|
Second
|
||||||
|
}
|
||||||
109
star_lock/lib/tools/pickers/time_picker/model/pduration.dart
Normal file
109
star_lock/lib/tools/pickers/time_picker/model/pduration.dart
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// import 'package:flutter_pickers/time_picker/model/date_type.dart';
|
||||||
|
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_type.dart';
|
||||||
|
|
||||||
|
/// 时间选择器 默认 时间设置
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// var s = PDuration.now();
|
||||||
|
/// print('longer1 >>> ${s.toString()}');
|
||||||
|
/// {year: 2021, month: 1, day: 5, hour: 17, minute: 17, second: 3}
|
||||||
|
///
|
||||||
|
/// var m = PDuration(year: 2011);
|
||||||
|
/// print('longer2 >>> ${m.toString()}');
|
||||||
|
/// {year: 2011, month: 0, day: 0, hour: 0, minute: 0, second: 0}
|
||||||
|
///
|
||||||
|
/// var d = PDuration.parse(DateTime.parse('20200304'));
|
||||||
|
/// print('longer3 >>> ${d.toString()}');
|
||||||
|
/// {year: 2020, month: 3, day: 4, hour: 0, minute: 0, second: 0}
|
||||||
|
|
||||||
|
bool intEmpty(int? value) {
|
||||||
|
return (value == null || value == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool intNotEmpty(int? value) {
|
||||||
|
return (value != null && value != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PDuration {
|
||||||
|
int? year;
|
||||||
|
int? month;
|
||||||
|
int? day;
|
||||||
|
int? hour;
|
||||||
|
int? minute;
|
||||||
|
int? second;
|
||||||
|
|
||||||
|
PDuration(
|
||||||
|
{this.year: 0,
|
||||||
|
this.month: 0,
|
||||||
|
this.day: 0,
|
||||||
|
this.hour: 0,
|
||||||
|
this.minute: 0,
|
||||||
|
this.second: 0});
|
||||||
|
|
||||||
|
// 注意默认会设为0 不是null
|
||||||
|
PDuration.parse(DateTime dateTime) {
|
||||||
|
this.year = dateTime.year;
|
||||||
|
this.month = dateTime.month;
|
||||||
|
this.day = dateTime.day;
|
||||||
|
this.hour = dateTime.hour;
|
||||||
|
this.minute = dateTime.minute;
|
||||||
|
this.second = dateTime.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDuration.now() {
|
||||||
|
var thisInstant = new DateTime.now();
|
||||||
|
this.year = thisInstant.year;
|
||||||
|
this.month = thisInstant.month;
|
||||||
|
this.day = thisInstant.day;
|
||||||
|
this.hour = thisInstant.hour;
|
||||||
|
this.minute = thisInstant.minute;
|
||||||
|
this.second = thisInstant.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSingle(DateType dateType, var value) {
|
||||||
|
switch (dateType) {
|
||||||
|
case DateType.Year:
|
||||||
|
this.year = value;
|
||||||
|
break;
|
||||||
|
case DateType.Month:
|
||||||
|
this.month = value;
|
||||||
|
break;
|
||||||
|
case DateType.Day:
|
||||||
|
this.day = value;
|
||||||
|
break;
|
||||||
|
case DateType.Hour:
|
||||||
|
this.hour = value;
|
||||||
|
break;
|
||||||
|
case DateType.Minute:
|
||||||
|
this.minute = value;
|
||||||
|
break;
|
||||||
|
case DateType.Second:
|
||||||
|
this.second = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 若为null 返回0
|
||||||
|
int getSingle(DateType dateType) {
|
||||||
|
switch (dateType) {
|
||||||
|
case DateType.Year:
|
||||||
|
return this.year ?? 0;
|
||||||
|
case DateType.Month:
|
||||||
|
return this.month ?? 0;
|
||||||
|
case DateType.Day:
|
||||||
|
return this.day ?? 0;
|
||||||
|
case DateType.Hour:
|
||||||
|
return this.hour ?? 0;
|
||||||
|
case DateType.Minute:
|
||||||
|
return this.minute ?? 0;
|
||||||
|
case DateType.Second:
|
||||||
|
return this.second ?? 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PDuration{year: $year, month: $month, day: $day, hour: $hour, minute: $minute, second: $second}';
|
||||||
|
}
|
||||||
|
}
|
||||||
47
star_lock/lib/tools/pickers/time_picker/model/suffix.dart
Normal file
47
star_lock/lib/tools/pickers/time_picker/model/suffix.dart
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// import 'package:flutter_pickers/time_picker/model/date_type.dart';
|
||||||
|
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_type.dart';
|
||||||
|
|
||||||
|
/// 后缀标签
|
||||||
|
class Suffix {
|
||||||
|
late String years;
|
||||||
|
late String month;
|
||||||
|
late String days;
|
||||||
|
late String hours;
|
||||||
|
late String minutes;
|
||||||
|
late String seconds;
|
||||||
|
|
||||||
|
Suffix.normal() {
|
||||||
|
this.years = '年';
|
||||||
|
this.month = '月';
|
||||||
|
this.days = '日';
|
||||||
|
this.hours = '时';
|
||||||
|
this.minutes = '分';
|
||||||
|
this.seconds = '秒';
|
||||||
|
}
|
||||||
|
|
||||||
|
Suffix(
|
||||||
|
{this.years: '',
|
||||||
|
this.month: '',
|
||||||
|
this.days: '',
|
||||||
|
this.hours: '',
|
||||||
|
this.minutes: '',
|
||||||
|
this.seconds: ''});
|
||||||
|
|
||||||
|
String getSingle(DateType dateType) {
|
||||||
|
switch (dateType) {
|
||||||
|
case DateType.Year:
|
||||||
|
return this.years;
|
||||||
|
case DateType.Month:
|
||||||
|
return this.month;
|
||||||
|
case DateType.Day:
|
||||||
|
return this.days;
|
||||||
|
case DateType.Hour:
|
||||||
|
return this.hours;
|
||||||
|
case DateType.Minute:
|
||||||
|
return this.minutes;
|
||||||
|
case DateType.Second:
|
||||||
|
return this.seconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,861 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/style/picker_style.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_item_model.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_time_data.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/date_type.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/pduration.dart';
|
||||||
|
import 'package:star_lock/tools/pickers/time_picker/model/suffix.dart';
|
||||||
|
// import 'package:flutter_pickers/style/picker_style.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/date_item_model.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/date_time_data.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/date_type.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/pduration.dart';
|
||||||
|
// import 'package:flutter_pickers/time_picker/model/suffix.dart';
|
||||||
|
|
||||||
|
import '../time_utils.dart';
|
||||||
|
|
||||||
|
typedef DateCallback(PDuration res);
|
||||||
|
|
||||||
|
class DatePickerRoute<T> extends PopupRoute<T> {
|
||||||
|
DatePickerRoute({
|
||||||
|
this.mode,
|
||||||
|
required this.initDate,
|
||||||
|
this.pickerStyle,
|
||||||
|
required this.maxDate,
|
||||||
|
required this.minDate,
|
||||||
|
this.suffix,
|
||||||
|
this.onChanged,
|
||||||
|
this.onConfirm,
|
||||||
|
this.onCancel,
|
||||||
|
this.theme,
|
||||||
|
this.barrierLabel,
|
||||||
|
RouteSettings? settings,
|
||||||
|
}) : super(settings: settings);
|
||||||
|
|
||||||
|
final DateMode? mode;
|
||||||
|
late final PDuration initDate;
|
||||||
|
late final PDuration maxDate;
|
||||||
|
late final PDuration minDate;
|
||||||
|
final Suffix? suffix;
|
||||||
|
final ThemeData? theme;
|
||||||
|
final DateCallback? onChanged;
|
||||||
|
final DateCallback? onConfirm;
|
||||||
|
final Function(bool isCancel)? onCancel;
|
||||||
|
final PickerStyle? pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => const Duration(milliseconds: 200);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get barrierDismissible => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool didPop(T? result) {
|
||||||
|
if (onCancel != null) {
|
||||||
|
if (result == null) {
|
||||||
|
onCancel!(false);
|
||||||
|
} else if (!(result as bool)) {
|
||||||
|
onCancel!(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.didPop(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String? barrierLabel;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color get barrierColor => Colors.black54;
|
||||||
|
|
||||||
|
AnimationController? _animationController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
AnimationController createAnimationController() {
|
||||||
|
assert(_animationController == null);
|
||||||
|
_animationController =
|
||||||
|
BottomSheet.createAnimationController(navigator!.overlay!);
|
||||||
|
return _animationController!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation) {
|
||||||
|
Widget bottomSheet = MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeTop: true,
|
||||||
|
child: _PickerContentView(
|
||||||
|
mode: mode,
|
||||||
|
initData: initDate,
|
||||||
|
maxDate: maxDate,
|
||||||
|
minDate: minDate,
|
||||||
|
pickerStyle: pickerStyle!,
|
||||||
|
route: this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (theme != null) {
|
||||||
|
bottomSheet = Theme(data: theme!, child: bottomSheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bottomSheet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerContentView extends StatefulWidget {
|
||||||
|
_PickerContentView({
|
||||||
|
Key? key,
|
||||||
|
this.mode,
|
||||||
|
required this.initData,
|
||||||
|
required this.pickerStyle,
|
||||||
|
required this.maxDate,
|
||||||
|
required this.minDate,
|
||||||
|
required this.route,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final DateMode? mode;
|
||||||
|
late final PDuration initData;
|
||||||
|
late final DatePickerRoute route;
|
||||||
|
late final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
// 限制时间
|
||||||
|
late final PDuration maxDate;
|
||||||
|
late final PDuration minDate;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _PickerState(
|
||||||
|
this.mode, this.initData, this.maxDate, this.minDate, this.pickerStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickerState extends State<_PickerContentView> {
|
||||||
|
late final PickerStyle _pickerStyle;
|
||||||
|
|
||||||
|
// 是否显示 [年月日时分秒]
|
||||||
|
late DateItemModel _dateItemModel;
|
||||||
|
|
||||||
|
// 初始 设置选中的数据
|
||||||
|
late final PDuration _initSelectData;
|
||||||
|
|
||||||
|
// 选中的数据 用于回传
|
||||||
|
late PDuration _selectData;
|
||||||
|
|
||||||
|
// 所有item 对应的数据
|
||||||
|
late DateTimeData _dateTimeData;
|
||||||
|
|
||||||
|
// 限制时间
|
||||||
|
late final PDuration maxDate;
|
||||||
|
late final PDuration minDate;
|
||||||
|
|
||||||
|
Animation<double>? animation;
|
||||||
|
Map<DateType, FixedExtentScrollController> scrollCtrl = {};
|
||||||
|
|
||||||
|
// 选择器 高度 单独提出来,用来解决修改数据 不及时更新的BUG
|
||||||
|
late double pickerItemHeight;
|
||||||
|
|
||||||
|
_PickerState(DateMode? mode, this._initSelectData, this.maxDate, this.minDate,
|
||||||
|
this._pickerStyle) {
|
||||||
|
this._dateItemModel = DateItemModel.parse(mode!);
|
||||||
|
this.pickerItemHeight = _pickerStyle.pickerItemHeight;
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
scrollCtrl.clear();
|
||||||
|
|
||||||
|
_dateTimeData = DateTimeData();
|
||||||
|
int index = 0; // 初始选中值 Index
|
||||||
|
_selectData = PDuration();
|
||||||
|
|
||||||
|
/// minDate 和 maxDate 都初始化了,可以省略很多空判断,直接比较选中值 是否相等 _selectData.month == minDate.month
|
||||||
|
/// -------年
|
||||||
|
if (_dateItemModel.year) {
|
||||||
|
index = 0;
|
||||||
|
_dateTimeData.year =
|
||||||
|
TimeUtils.calcYears(begin: minDate.year!, end: maxDate.year!);
|
||||||
|
|
||||||
|
if (_initSelectData.year != null) {
|
||||||
|
index = _dateTimeData.year.indexOf(_initSelectData.year);
|
||||||
|
index = index < 0 ? 0 : index;
|
||||||
|
}
|
||||||
|
_selectData.year = _dateTimeData.year[index];
|
||||||
|
scrollCtrl[DateType.Year] =
|
||||||
|
FixedExtentScrollController(initialItem: index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------月
|
||||||
|
// 选中的月 用于之后 day 的计算
|
||||||
|
int selectMonth = 1;
|
||||||
|
if (_dateItemModel.month) {
|
||||||
|
index = 0;
|
||||||
|
int begin = 1;
|
||||||
|
int end = 12;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.month) && _selectData.year == minDate.year) {
|
||||||
|
begin = minDate.month!;
|
||||||
|
}
|
||||||
|
if (intNotEmpty(maxDate.month) && _selectData.year == maxDate.year) {
|
||||||
|
end = maxDate.month!;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dateTimeData.month = TimeUtils.calcMonth(begin: begin, end: end);
|
||||||
|
|
||||||
|
if (_initSelectData.month != null) {
|
||||||
|
index = _dateTimeData.month.indexOf(_initSelectData.month);
|
||||||
|
index = index < 0 ? 0 : index;
|
||||||
|
}
|
||||||
|
selectMonth = _dateTimeData.month[index];
|
||||||
|
_selectData.month = selectMonth;
|
||||||
|
scrollCtrl[DateType.Month] =
|
||||||
|
FixedExtentScrollController(initialItem: index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// -------日 (有日肯定有 年月数据)
|
||||||
|
if (_dateItemModel.day) {
|
||||||
|
index = 0;
|
||||||
|
int begin = 1;
|
||||||
|
int end = 31;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) {
|
||||||
|
if (_selectData.year == minDate.year &&
|
||||||
|
_selectData.month == minDate.month) {
|
||||||
|
begin = minDate.day!;
|
||||||
|
}
|
||||||
|
if (_selectData.year == maxDate.year &&
|
||||||
|
_selectData.month == maxDate.month) {
|
||||||
|
end = maxDate.day!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_dateTimeData.day = TimeUtils.calcDay(_initSelectData.year!, selectMonth,
|
||||||
|
begin: begin, end: end);
|
||||||
|
|
||||||
|
if (_initSelectData.day != null) {
|
||||||
|
index = _dateTimeData.day.indexOf(_initSelectData.day);
|
||||||
|
index = index < 0 ? 0 : index;
|
||||||
|
}
|
||||||
|
_selectData.day = _dateTimeData.day[index];
|
||||||
|
scrollCtrl[DateType.Day] =
|
||||||
|
FixedExtentScrollController(initialItem: index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------时
|
||||||
|
if (_dateItemModel.hour) {
|
||||||
|
index = 0;
|
||||||
|
int begin = 0;
|
||||||
|
int end = 23;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.hour)) {
|
||||||
|
begin = minDate.hour!;
|
||||||
|
}
|
||||||
|
if (intNotEmpty(maxDate.hour)) {
|
||||||
|
end = maxDate.hour!;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dateTimeData.hour = TimeUtils.calcHour(begin: begin, end: end);
|
||||||
|
|
||||||
|
if (_initSelectData.hour != null) {
|
||||||
|
index = _dateTimeData.hour.indexOf(_initSelectData.hour);
|
||||||
|
index = index < 0 ? 0 : index;
|
||||||
|
}
|
||||||
|
_selectData.hour = _dateTimeData.hour[index];
|
||||||
|
scrollCtrl[DateType.Hour] =
|
||||||
|
FixedExtentScrollController(initialItem: index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------分
|
||||||
|
if (_dateItemModel.minute) {
|
||||||
|
index = 0;
|
||||||
|
int begin = 0;
|
||||||
|
int end = 59;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.minute) || intNotEmpty(maxDate.minute)) {
|
||||||
|
if (_dateItemModel.hour) {
|
||||||
|
// 如果有上级 还有时,要根据时再判断
|
||||||
|
if (_selectData.hour == minDate.hour) {
|
||||||
|
begin = minDate.minute!;
|
||||||
|
}
|
||||||
|
if (_selectData.hour == maxDate.hour) {
|
||||||
|
end = maxDate.minute!;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 上级没有时间限制 直接取
|
||||||
|
if (intNotEmpty(minDate.minute)) {
|
||||||
|
begin = minDate.minute!;
|
||||||
|
}
|
||||||
|
if (intNotEmpty(maxDate.minute)) {
|
||||||
|
end = maxDate.minute!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_dateTimeData.minute = TimeUtils.calcMinAndSecond(begin: begin, end: end);
|
||||||
|
|
||||||
|
if (_initSelectData.minute != null) {
|
||||||
|
index = _dateTimeData.minute.indexOf(_initSelectData.minute);
|
||||||
|
index = index < 0 ? 0 : index;
|
||||||
|
}
|
||||||
|
_selectData.minute = _dateTimeData.minute[index];
|
||||||
|
scrollCtrl[DateType.Minute] =
|
||||||
|
FixedExtentScrollController(initialItem: index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// --------秒
|
||||||
|
if (_dateItemModel.second) {
|
||||||
|
index = 0;
|
||||||
|
int begin = 0;
|
||||||
|
int end = 59;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) {
|
||||||
|
if (_dateItemModel.hour && _dateItemModel.minute) {
|
||||||
|
// 如果有上级 还有时 分,要根据时分再判断
|
||||||
|
if (_selectData.hour == minDate.hour &&
|
||||||
|
_selectData.minute == minDate.minute) {
|
||||||
|
begin = minDate.second!;
|
||||||
|
}
|
||||||
|
if (_selectData.hour == maxDate.hour &&
|
||||||
|
_selectData.minute == maxDate.minute) {
|
||||||
|
end = maxDate.second!;
|
||||||
|
}
|
||||||
|
} else if (_dateItemModel.minute) {
|
||||||
|
/// 上级没有时,只有分限制
|
||||||
|
if (_selectData.minute == minDate.minute) {
|
||||||
|
begin = minDate.second!;
|
||||||
|
}
|
||||||
|
if (_selectData.minute == maxDate.minute) {
|
||||||
|
end = maxDate.second!;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/// 上级没有时间限制 直接取
|
||||||
|
if (intNotEmpty(minDate.second)) {
|
||||||
|
begin = minDate.second!;
|
||||||
|
}
|
||||||
|
if (intNotEmpty(maxDate.second)) {
|
||||||
|
end = maxDate.second!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_dateTimeData.second = TimeUtils.calcMinAndSecond(begin: begin, end: end);
|
||||||
|
|
||||||
|
if (_initSelectData.second != null) {
|
||||||
|
index = _dateTimeData.second.indexOf(_initSelectData.second);
|
||||||
|
index = index < 0 ? 0 : index;
|
||||||
|
}
|
||||||
|
_selectData.second = _dateTimeData.second[index];
|
||||||
|
scrollCtrl[DateType.Second] =
|
||||||
|
FixedExtentScrollController(initialItem: index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
scrollCtrl.forEach((key, value) {
|
||||||
|
value.dispose();
|
||||||
|
});
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: AnimatedBuilder(
|
||||||
|
animation: widget.route.animation!,
|
||||||
|
builder: (BuildContext context, Widget? child) {
|
||||||
|
return ClipRect(
|
||||||
|
child: CustomSingleChildLayout(
|
||||||
|
delegate: _BottomPickerLayout(
|
||||||
|
widget.route.animation!.value, _pickerStyle),
|
||||||
|
child: GestureDetector(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: _renderPickerView(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setPicker(DateType dateType, int selectIndex) {
|
||||||
|
// 得到新的选中的数据
|
||||||
|
var selectValue = _dateTimeData.getListByName(dateType)[selectIndex];
|
||||||
|
// 更新选中数据
|
||||||
|
_selectData.setSingle(dateType, selectValue);
|
||||||
|
|
||||||
|
switch (dateType) {
|
||||||
|
case DateType.Year:
|
||||||
|
_setYear();
|
||||||
|
break;
|
||||||
|
case DateType.Month:
|
||||||
|
_setMonth();
|
||||||
|
break;
|
||||||
|
case DateType.Day:
|
||||||
|
break;
|
||||||
|
case DateType.Hour:
|
||||||
|
_setHour();
|
||||||
|
break;
|
||||||
|
case DateType.Minute:
|
||||||
|
_setMinute();
|
||||||
|
break;
|
||||||
|
case DateType.Second:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_notifyLocationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- set begin ------------
|
||||||
|
void _setYear() {
|
||||||
|
// 可能造成 月 日 list的改变
|
||||||
|
if (_dateItemModel.month) {
|
||||||
|
// 月的数据是否需要更新
|
||||||
|
bool updateMonth = false;
|
||||||
|
bool updateDay = false;
|
||||||
|
|
||||||
|
/// 如果只有月
|
||||||
|
int beginMonth = 1;
|
||||||
|
int endMonth = 12;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.month) && _selectData.year == minDate.year) {
|
||||||
|
beginMonth = minDate.month!;
|
||||||
|
}
|
||||||
|
if (intNotEmpty(maxDate.month) && _selectData.year == maxDate.year) {
|
||||||
|
endMonth = maxDate.month!;
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultMonth = TimeUtils.calcMonth(begin: beginMonth, end: endMonth);
|
||||||
|
|
||||||
|
int jumpToIndexMonth = 0;
|
||||||
|
|
||||||
|
if (!listEquals(_dateTimeData.month, resultMonth)) {
|
||||||
|
//可能 选中的月份 由于设置了新数据后没有了
|
||||||
|
// 小于不用考虑 会进else
|
||||||
|
if (_selectData.month! > resultMonth.last) {
|
||||||
|
jumpToIndexMonth = resultMonth.length - 1;
|
||||||
|
} else {
|
||||||
|
jumpToIndexMonth = resultMonth.indexOf(_selectData.month);
|
||||||
|
}
|
||||||
|
jumpToIndexMonth = jumpToIndexMonth < 0 ? 0 : jumpToIndexMonth;
|
||||||
|
_selectData.month = resultMonth[jumpToIndexMonth];
|
||||||
|
updateMonth = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 还有 日
|
||||||
|
int jumpToIndexDay = 0;
|
||||||
|
// 新的day 数据
|
||||||
|
var resultDay;
|
||||||
|
if (_dateItemModel.day) {
|
||||||
|
int beginDay = 1;
|
||||||
|
int endDay = 31;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) {
|
||||||
|
if (_selectData.year == minDate.year &&
|
||||||
|
_selectData.month == minDate.month) {
|
||||||
|
beginDay = minDate.day!;
|
||||||
|
}
|
||||||
|
if (_selectData.year == maxDate.year &&
|
||||||
|
_selectData.month == maxDate.month) {
|
||||||
|
endDay = maxDate.day!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultDay = TimeUtils.calcDay(_selectData.year!, _selectData.month!,
|
||||||
|
begin: beginDay, end: endDay);
|
||||||
|
|
||||||
|
if (!listEquals(_dateTimeData.day, resultDay)) {
|
||||||
|
//可能 选中的年 月份 由于设置了新数据后没有了
|
||||||
|
// 小于不用考虑 会进else
|
||||||
|
if (_selectData.day! > resultDay.last) {
|
||||||
|
jumpToIndexDay = resultDay.length - 1;
|
||||||
|
} else {
|
||||||
|
jumpToIndexDay = resultDay.indexOf(_selectData.day);
|
||||||
|
}
|
||||||
|
jumpToIndexDay = jumpToIndexDay < 0 ? 0 : jumpToIndexDay;
|
||||||
|
_selectData.day = resultDay[jumpToIndexDay];
|
||||||
|
updateDay = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateMonth || updateDay) {
|
||||||
|
setState(() {
|
||||||
|
if (updateMonth) {
|
||||||
|
_dateTimeData.month = resultMonth;
|
||||||
|
scrollCtrl[DateType.Month]?.jumpToItem(jumpToIndexMonth);
|
||||||
|
}
|
||||||
|
if (updateDay) {
|
||||||
|
_dateTimeData.day = resultDay;
|
||||||
|
scrollCtrl[DateType.Day]?.jumpToItem(jumpToIndexDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// FIX:https://github.com/flutter/flutter/issues/22999
|
||||||
|
pickerItemHeight =
|
||||||
|
_pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setMonth() {
|
||||||
|
// 可能造成 日 list的改变
|
||||||
|
bool updateDay = false;
|
||||||
|
int jumpToIndexDay = 0;
|
||||||
|
// 新的day 数据
|
||||||
|
var resultDay;
|
||||||
|
if (_dateItemModel.day) {
|
||||||
|
int beginDay = 1;
|
||||||
|
int endDay = 31;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.day) || intNotEmpty(maxDate.day)) {
|
||||||
|
if (_selectData.year == minDate.year &&
|
||||||
|
_selectData.month == minDate.month) {
|
||||||
|
beginDay = minDate.day!;
|
||||||
|
}
|
||||||
|
if (_selectData.year == maxDate.year &&
|
||||||
|
_selectData.month == maxDate.month) {
|
||||||
|
endDay = maxDate.day!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultDay = TimeUtils.calcDay(_selectData.year!, _selectData.month!,
|
||||||
|
begin: beginDay, end: endDay);
|
||||||
|
|
||||||
|
if (!listEquals(_dateTimeData.day, resultDay)) {
|
||||||
|
//可能 选中的年 月份 由于设置了新数据后没有了
|
||||||
|
// 小于不用考虑 会进else
|
||||||
|
if (_selectData.day! > resultDay.last) {
|
||||||
|
jumpToIndexDay = resultDay.length - 1;
|
||||||
|
} else {
|
||||||
|
jumpToIndexDay = resultDay.indexOf(_selectData.day);
|
||||||
|
}
|
||||||
|
jumpToIndexDay = jumpToIndexDay < 0 ? 0 : jumpToIndexDay;
|
||||||
|
_selectData.day = resultDay[jumpToIndexDay];
|
||||||
|
updateDay = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (updateDay) {
|
||||||
|
setState(() {
|
||||||
|
_dateTimeData.day = resultDay;
|
||||||
|
scrollCtrl[DateType.Day]?.jumpToItem(jumpToIndexDay);
|
||||||
|
|
||||||
|
/// FIX:https://github.com/flutter/flutter/issues/22999
|
||||||
|
pickerItemHeight =
|
||||||
|
_pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setHour() {
|
||||||
|
// 可能造成 分 秒 list的改变
|
||||||
|
if (_dateItemModel.minute) {
|
||||||
|
// 月的数据是否需要更新
|
||||||
|
bool updateMinute = false;
|
||||||
|
bool updateSecond = false;
|
||||||
|
|
||||||
|
/// 如果只有分
|
||||||
|
int beginMinute = 0;
|
||||||
|
int endMinute = 59;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.minute) && _selectData.hour == minDate.hour) {
|
||||||
|
beginMinute = minDate.minute!;
|
||||||
|
}
|
||||||
|
if (intNotEmpty(maxDate.minute) && _selectData.hour == maxDate.hour) {
|
||||||
|
endMinute = maxDate.minute!;
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultMinute =
|
||||||
|
TimeUtils.calcMinAndSecond(begin: beginMinute, end: endMinute);
|
||||||
|
|
||||||
|
int jumpToIndexMinute = 0;
|
||||||
|
|
||||||
|
if (!listEquals(_dateTimeData.month, resultMinute)) {
|
||||||
|
//可能 选中的时间 由于设置了新数据后没有了
|
||||||
|
// 小于不用考虑 会进else
|
||||||
|
if (_selectData.minute! > resultMinute.last) {
|
||||||
|
jumpToIndexMinute = resultMinute.length - 1;
|
||||||
|
} else {
|
||||||
|
jumpToIndexMinute = resultMinute.indexOf(_selectData.minute);
|
||||||
|
}
|
||||||
|
jumpToIndexMinute = jumpToIndexMinute < 0 ? 0 : jumpToIndexMinute;
|
||||||
|
_selectData.minute = resultMinute[jumpToIndexMinute];
|
||||||
|
updateMinute = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 还有 秒
|
||||||
|
int jumpToIndexSecond = 0;
|
||||||
|
// 新的day 数据
|
||||||
|
var resultSecond;
|
||||||
|
if (_dateItemModel.second) {
|
||||||
|
int beginSecond = 0;
|
||||||
|
int endSecond = 59;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) {
|
||||||
|
if (_selectData.hour == minDate.hour &&
|
||||||
|
_selectData.minute == minDate.minute) {
|
||||||
|
beginSecond = minDate.second!;
|
||||||
|
}
|
||||||
|
if (_selectData.hour == maxDate.hour &&
|
||||||
|
_selectData.minute == maxDate.minute) {
|
||||||
|
endSecond = maxDate.second!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultSecond =
|
||||||
|
TimeUtils.calcMinAndSecond(begin: beginSecond, end: endSecond);
|
||||||
|
|
||||||
|
if (!listEquals(_dateTimeData.second, resultSecond)) {
|
||||||
|
//可能 选中的时 分 由于设置了新数据后没有了
|
||||||
|
// 小于不用考虑 会进else
|
||||||
|
if (_selectData.second! > resultSecond.last) {
|
||||||
|
jumpToIndexSecond = resultSecond.length - 1;
|
||||||
|
} else {
|
||||||
|
jumpToIndexSecond = resultSecond.indexOf(_selectData.second);
|
||||||
|
}
|
||||||
|
jumpToIndexSecond = jumpToIndexSecond < 0 ? 0 : jumpToIndexSecond;
|
||||||
|
_selectData.second = resultSecond[jumpToIndexSecond];
|
||||||
|
updateSecond = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateMinute || updateSecond) {
|
||||||
|
setState(() {
|
||||||
|
if (updateMinute) {
|
||||||
|
_dateTimeData.minute = resultMinute;
|
||||||
|
scrollCtrl[DateType.Minute]?.jumpToItem(jumpToIndexMinute);
|
||||||
|
}
|
||||||
|
if (updateSecond) {
|
||||||
|
_dateTimeData.second = resultSecond;
|
||||||
|
scrollCtrl[DateType.Second]?.jumpToItem(jumpToIndexSecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// FIX:https://github.com/flutter/flutter/issues/22999
|
||||||
|
pickerItemHeight =
|
||||||
|
_pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setMinute() {
|
||||||
|
// 可能造成 秒 list的改变
|
||||||
|
bool updateSecond = false;
|
||||||
|
int jumpToIndexSecond = 0;
|
||||||
|
// 新的day 数据
|
||||||
|
var resultSecond;
|
||||||
|
if (_dateItemModel.second) {
|
||||||
|
int beginSecond = 0;
|
||||||
|
int endSecond = 59;
|
||||||
|
// 限制区域
|
||||||
|
if (intNotEmpty(minDate.second) || intNotEmpty(maxDate.second)) {
|
||||||
|
if (_dateItemModel.hour) {
|
||||||
|
// 如果上面还有 时
|
||||||
|
if (_selectData.hour == minDate.hour &&
|
||||||
|
_selectData.minute == minDate.minute) {
|
||||||
|
beginSecond = minDate.second!;
|
||||||
|
}
|
||||||
|
if (_selectData.hour == maxDate.hour &&
|
||||||
|
_selectData.minute == maxDate.minute) {
|
||||||
|
endSecond = maxDate.second!;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 没有时,分秒
|
||||||
|
if (_selectData.minute == minDate.minute) {
|
||||||
|
beginSecond = minDate.second!;
|
||||||
|
}
|
||||||
|
if (_selectData.minute == maxDate.minute) {
|
||||||
|
endSecond = maxDate.second!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultSecond =
|
||||||
|
TimeUtils.calcMinAndSecond(begin: beginSecond, end: endSecond);
|
||||||
|
|
||||||
|
if (!listEquals(_dateTimeData.second, resultSecond)) {
|
||||||
|
//可能 选中的分 由于设置了新数据后没有了
|
||||||
|
// 小于不用考虑 会进else
|
||||||
|
if (_selectData.second! > resultSecond.last) {
|
||||||
|
jumpToIndexSecond = resultSecond.length - 1;
|
||||||
|
} else {
|
||||||
|
jumpToIndexSecond = resultSecond.indexOf(_selectData.second);
|
||||||
|
}
|
||||||
|
jumpToIndexSecond = jumpToIndexSecond < 0 ? 0 : jumpToIndexSecond;
|
||||||
|
_selectData.second = resultSecond[jumpToIndexSecond];
|
||||||
|
updateSecond = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (updateSecond) {
|
||||||
|
setState(() {
|
||||||
|
_dateTimeData.second = resultSecond;
|
||||||
|
scrollCtrl[DateType.Second]?.jumpToItem(jumpToIndexSecond);
|
||||||
|
|
||||||
|
/// FIX:https://github.com/flutter/flutter/issues/22999
|
||||||
|
pickerItemHeight =
|
||||||
|
_pickerStyle.pickerItemHeight - Random().nextDouble() / 100000000;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- set end ------------
|
||||||
|
|
||||||
|
void _notifyLocationChanged() {
|
||||||
|
if (widget.route.onChanged != null) {
|
||||||
|
widget.route.onChanged!(_selectData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double _pickerFontSize(String text) {
|
||||||
|
if (text == '') return 18.0;
|
||||||
|
|
||||||
|
if (_dateItemModel.length == 6 && (text.length > 4 && text.length <= 6)) {
|
||||||
|
return 16.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.length <= 6) {
|
||||||
|
return 18.0;
|
||||||
|
} else if (text.length < 9) {
|
||||||
|
return 16.0;
|
||||||
|
} else if (text.length < 13) {
|
||||||
|
return 12.0;
|
||||||
|
} else {
|
||||||
|
return 10.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderPickerView() {
|
||||||
|
Widget itemView = _renderItemView();
|
||||||
|
|
||||||
|
if (!_pickerStyle.showTitleBar && _pickerStyle.menu == null) {
|
||||||
|
return itemView;
|
||||||
|
}
|
||||||
|
List<Widget> viewList = <Widget>[];
|
||||||
|
if (_pickerStyle.showTitleBar) {
|
||||||
|
viewList.add(_titleView());
|
||||||
|
}
|
||||||
|
if (_pickerStyle.menu != null) {
|
||||||
|
viewList.add(_pickerStyle.menu!);
|
||||||
|
}
|
||||||
|
viewList.add(itemView);
|
||||||
|
|
||||||
|
return Column(children: viewList);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderItemView() {
|
||||||
|
// 选择器
|
||||||
|
List<Widget> pickerList = [];
|
||||||
|
if (_dateItemModel.year) pickerList.add(pickerView(DateType.Year));
|
||||||
|
if (_dateItemModel.month) pickerList.add(pickerView(DateType.Month));
|
||||||
|
if (_dateItemModel.day) pickerList.add(pickerView(DateType.Day));
|
||||||
|
if (_dateItemModel.hour) pickerList.add(pickerView(DateType.Hour));
|
||||||
|
if (_dateItemModel.minute) pickerList.add(pickerView(DateType.Minute));
|
||||||
|
if (_dateItemModel.second) pickerList.add(pickerView(DateType.Second));
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerHeight,
|
||||||
|
color: _pickerStyle.backgroundColor,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: pickerList,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// CupertinoPicker.builder
|
||||||
|
Widget pickerView(DateType dateType) {
|
||||||
|
return Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||||
|
child: CupertinoPicker.builder(
|
||||||
|
/// key :年月拼接 就不会重复了 fixme
|
||||||
|
/// 最好别使用key 会生成新的widget
|
||||||
|
/// 官方的bug : https://github.com/flutter/flutter/issues/22999
|
||||||
|
/// 临时方法 通过修改height
|
||||||
|
scrollController: scrollCtrl[dateType],
|
||||||
|
itemExtent: pickerItemHeight,
|
||||||
|
selectionOverlay: _pickerStyle.itemOverlay,
|
||||||
|
onSelectedItemChanged: (int selectIndex) =>
|
||||||
|
_setPicker(dateType, selectIndex),
|
||||||
|
childCount: _dateTimeData.getListByName(dateType).length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
String text =
|
||||||
|
'${_dateTimeData.getListByName(dateType)[index]}${widget.route.suffix?.getSingle(dateType)}';
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(text,
|
||||||
|
style: TextStyle(
|
||||||
|
color: _pickerStyle.textColor,
|
||||||
|
fontSize: _pickerStyle.textSize ?? _pickerFontSize(text),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择器上面的view
|
||||||
|
Widget _titleView() {
|
||||||
|
return Container(
|
||||||
|
height: _pickerStyle.pickerTitleHeight,
|
||||||
|
decoration: _pickerStyle.headDecoration,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
/// 取消按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () => Navigator.pop(context, false),
|
||||||
|
child: _pickerStyle.cancelButton),
|
||||||
|
|
||||||
|
/// 标题
|
||||||
|
Expanded(child: _pickerStyle.title),
|
||||||
|
|
||||||
|
/// 确认按钮
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.route.onConfirm != null) {
|
||||||
|
widget.route.onConfirm!(_selectData);
|
||||||
|
}
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
child: _pickerStyle.commitButton)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BottomPickerLayout extends SingleChildLayoutDelegate {
|
||||||
|
_BottomPickerLayout(this.progress, this.pickerStyle);
|
||||||
|
|
||||||
|
final double progress;
|
||||||
|
final PickerStyle pickerStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
||||||
|
double maxHeight = pickerStyle.pickerHeight;
|
||||||
|
if (pickerStyle.showTitleBar) {
|
||||||
|
maxHeight += pickerStyle.pickerTitleHeight;
|
||||||
|
}
|
||||||
|
if (pickerStyle.menu != null) {
|
||||||
|
maxHeight += pickerStyle.menuHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoxConstraints(
|
||||||
|
minWidth: constraints.maxWidth,
|
||||||
|
maxWidth: constraints.maxWidth,
|
||||||
|
minHeight: 0.0,
|
||||||
|
maxHeight: maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Offset getPositionForChild(Size size, Size childSize) {
|
||||||
|
double height = size.height - childSize.height * progress;
|
||||||
|
return Offset(0.0, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRelayout(_BottomPickerLayout oldDelegate) {
|
||||||
|
return progress != oldDelegate.progress;
|
||||||
|
}
|
||||||
|
}
|
||||||
73
star_lock/lib/tools/pickers/time_picker/time_utils.dart
Normal file
73
star_lock/lib/tools/pickers/time_picker/time_utils.dart
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
class TimeUtils {
|
||||||
|
/// 年
|
||||||
|
static List calcYears({int begin = 1900, int end = 2100}) =>
|
||||||
|
_calcCount(begin, end);
|
||||||
|
|
||||||
|
/// 月
|
||||||
|
static List calcMonth({int begin = 1, int end = 12}) {
|
||||||
|
begin = begin < 1 ? 1 : begin;
|
||||||
|
end = end > 12 ? 12 : end;
|
||||||
|
return _calcCount(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 日
|
||||||
|
static List calcDay(int year, int month, {int begin = 1, int end = 31}) {
|
||||||
|
begin = begin < 1 ? 1 : begin;
|
||||||
|
|
||||||
|
int days = _calcDateCount(year, month);
|
||||||
|
if (end > days) {
|
||||||
|
end = days;
|
||||||
|
}
|
||||||
|
return _calcCount(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 时
|
||||||
|
static List calcHour({int begin = 0, int end = 23}) {
|
||||||
|
begin = begin < 0 ? 0 : begin;
|
||||||
|
end = end > 23 ? 23 : end;
|
||||||
|
return _calcCount(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 分 和 秒
|
||||||
|
static List calcMinAndSecond({int begin = 0, int end = 59}) {
|
||||||
|
begin = begin < 0 ? 0 : begin;
|
||||||
|
end = end > 59 ? 59 : end;
|
||||||
|
return _calcCount(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static List _calcCount(begin, end) {
|
||||||
|
int length = end - begin + 1;
|
||||||
|
if (length == 0) return [begin];
|
||||||
|
if (length < 0) return [];
|
||||||
|
|
||||||
|
return List.generate(length, (index) => begin + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算月份所对应天数
|
||||||
|
static int _calcDateCount(int year, int month) {
|
||||||
|
switch (month) {
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
return 31;
|
||||||
|
case 2:
|
||||||
|
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
|
||||||
|
return 29;
|
||||||
|
}
|
||||||
|
return 28;
|
||||||
|
}
|
||||||
|
return 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
String intToStr(int v) {
|
||||||
|
return (v < 10) ? "0$v" : "$v";
|
||||||
|
}
|
||||||
|
|
||||||
|
// String _checkStr(String v) {
|
||||||
|
// return v == null ? "" : v;
|
||||||
|
// }
|
||||||
|
}
|
||||||
45
star_lock/lib/tools/pickers/utils/check.dart
Normal file
45
star_lock/lib/tools/pickers/utils/check.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
class PicketUtil {
|
||||||
|
/// 字符串不为空
|
||||||
|
static bool strNoEmpty(String? value) {
|
||||||
|
if (value == null) return false;
|
||||||
|
|
||||||
|
return value.trim().isNotEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 字符串为空
|
||||||
|
static bool strEmpty(String? value) {
|
||||||
|
if (value == null) return true;
|
||||||
|
|
||||||
|
return value.trim().isEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MAp不为空
|
||||||
|
static bool mapNoEmpty(Map? value) {
|
||||||
|
if (value == null) return false;
|
||||||
|
return value.isNotEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MAp为空
|
||||||
|
static bool mapEmpty(Map? value) {
|
||||||
|
if (value == null) return true;
|
||||||
|
return value.isEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
///判断List是否为空
|
||||||
|
static bool listNoEmpty(List? list) {
|
||||||
|
if (list == null) return false;
|
||||||
|
|
||||||
|
if (list.length == 0) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///判断List是否为空
|
||||||
|
static bool listEmpty(List? list) {
|
||||||
|
if (list == null) return true;
|
||||||
|
|
||||||
|
if (list.length == 0) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -64,7 +64,7 @@ dependencies:
|
|||||||
#生成二维码
|
#生成二维码
|
||||||
qr_flutter: ^4.1.0
|
qr_flutter: ^4.1.0
|
||||||
#底部选择
|
#底部选择
|
||||||
flutter_pickers: ^2.1.9
|
#flutter_pickers: ^2.1.9
|
||||||
#万年历
|
#万年历
|
||||||
syncfusion_flutter_datepicker: ^22.1.38
|
syncfusion_flutter_datepicker: ^22.1.38
|
||||||
#使用相机及相册
|
#使用相机及相册
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user