Commit 4da6781a9addcce11a690d5b72c04c85f0517b7e

Authored by weixin_45529955
1 parent bc0046b8

农历阳历时间picker本地化修改

Showing 93 changed files with 4043 additions and 102 deletions
@@ -171,7 +171,7 @@ class _MyCustomerListPageState extends State<MyCustomerListPage> @@ -171,7 +171,7 @@ class _MyCustomerListPageState extends State<MyCustomerListPage>
171 } 171 }
172 172
173 getSellerVersion() async { 173 getSellerVersion() async {
174 - await collectStoreProvider.getSellerVersion(context); 174 + await collectStoreProvider.getSellerVersion(context,showLoading: false);
175 175
176 setState(() {}); 176 setState(() {});
177 } 177 }
@@ -992,13 +992,13 @@ class _CustomerDetailPageState extends State<CustomerDetailPage> { @@ -992,13 +992,13 @@ class _CustomerDetailPageState extends State<CustomerDetailPage> {
992 color: MyColours.color_333333), 992 color: MyColours.color_333333),
993 ), 993 ),
994 Spacer(), 994 Spacer(),
995 - Text(  
996 - birthday,  
997 - style: TextStyle(  
998 - fontSize: ScreenUtil().setSp(26),  
999 - color: MyColours.color_333333),  
1000 - ),  
1001 - HEmptyView(20), 995 + // Text(
  996 + // birthday,
  997 + // style: TextStyle(
  998 + // fontSize: ScreenUtil().setSp(26),
  999 + // color: MyColours.color_333333),
  1000 + // ),
  1001 + // HEmptyView(20),
1002 RoundButton( 1002 RoundButton(
1003 text: '编辑', 1003 text: '编辑',
1004 radius: ScreenUtil().setWidth(20), 1004 radius: ScreenUtil().setWidth(20),
@@ -1007,42 +1007,9 @@ class _CustomerDetailPageState extends State<CustomerDetailPage> { @@ -1007,42 +1007,9 @@ class _CustomerDetailPageState extends State<CustomerDetailPage> {
1007 fontSize: 26, 1007 fontSize: 26,
1008 isBold: false, 1008 isBold: false,
1009 onPressed: () { 1009 onPressed: () {
1010 - DialogUtil.showPickerDateTime24(  
1011 - context,  
1012 - scaffoldKey,  
1013 - (value) async {  
1014 - // {'text': picker.adapter.text, 'select': selecteds}  
1015 - if (value != null) {  
1016 - setState(() {  
1017 - print(value);  
1018 - birthday = DateUtil.formatDateStr(value,  
1019 - format: DateFormats.y_mo_d);  
1020 - });  
1021 - // 请求接口,设置生日  
1022 - String from = birthday + ' 00:00:00';  
1023 - Map<String, String?> params = {  
1024 - 'id': widget.userHistoryEntity!.gid,  
1025 - 'c_day':  
1026 - '${(DateUtil.getDateMsByTimeStr(from)! / 1000).floor()}',  
1027 - };  
1028 - bool sucess = await customerProvider  
1029 - .setGuestInfo(context, params,  
1030 - showLoading: true);  
1031 - if (sucess) {  
1032 - Utils.showToast('保存成功');  
1033 - }  
1034 - }  
1035 - // showDateSelWidget = false;  
1036 - },  
1037 - yearBegin: 1925,  
1038 - minValue: DateTime(1925),  
1039 - dateTime: birthday == ''  
1040 - ? DateTime.now()  
1041 - : DateUtil.getDateTime(birthday),  
1042 - pickerDateTimeType: PickerDateTimeType.kYMD,  
1043 - onCancel: () {  
1044 - // showDateSelWidget = false;  
1045 - }); 1010 +
  1011 + NavigatorUtil.goSetBirthdayPage(context,widget.userHistoryEntity!.gid);
  1012 +
1046 }, 1013 },
1047 ), 1014 ),
1048 ], 1015 ],
@@ -266,7 +266,7 @@ class _CustomerListPageState extends State<CustomerListPage> @@ -266,7 +266,7 @@ class _CustomerListPageState extends State<CustomerListPage>
266 } 266 }
267 267
268 getSellerVersion() async { 268 getSellerVersion() async {
269 - await collectStoreProvider.getSellerVersion(context); 269 + await collectStoreProvider.getSellerVersion(context,showLoading: false);
270 270
271 setState(() {}); 271 setState(() {});
272 } 272 }
  1 +import 'package:common_utils/common_utils.dart';
  2 +import 'package:flutter/material.dart';
  3 +import 'package:flutter_lunar_datetime_picker/date_init.dart';
  4 +import 'package:flutter_picker_plus/picker.dart';
  5 +import 'package:one_key/provider/customer_provider.dart';
  6 +import 'package:one_key/res/colors.dart';
  7 +import 'package:one_key/utils/dialog_util.dart';
  8 +import 'package:one_key/utils/screen_util.dart';
  9 +import 'package:one_key/utils/utils.dart';
  10 +import 'package:one_key/widgets/MyDivider.dart';
  11 +import 'package:one_key/widgets/h_empty_view.dart';
  12 +import 'package:one_key/widgets/system_app_bar.dart';
  13 +import 'package:one_key/widgets/v_empty_view.dart';
  14 +import 'package:provider/provider.dart';
  15 +
  16 +import 'package:flutter_lunar_datetime_picker/flutter_lunar_datetime_picker.dart';
  17 +import 'package:flutter_lunar_datetime_picker/datetime_picker_theme.dart'
  18 + as picker_theme;
  19 +
  20 +/**
  21 + * 客户生日编辑页面
  22 + */
  23 +class SetBirthdayPage extends StatefulWidget {
  24 + final String? gid;
  25 + const SetBirthdayPage({super.key, required this.gid});
  26 +
  27 + @override
  28 + State<SetBirthdayPage> createState() => _SetBirthdayPageState();
  29 +}
  30 +
  31 +class _SetBirthdayPageState extends State<SetBirthdayPage> {
  32 + late CustomerProvider customerProvider;
  33 + final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
  34 + String birthday = '';
  35 +
  36 + _item(
  37 + String title,
  38 + String subTitle, {
  39 + GestureTapCallback? onTapDel,
  40 + GestureTapCallback? onTapEdit,
  41 + }) {
  42 + return Container(
  43 + padding: EdgeInsets.all(w(10)),
  44 + margin: EdgeInsets.symmetric(horizontal: w(20)),
  45 + child: Column(
  46 + crossAxisAlignment: CrossAxisAlignment.start,
  47 + children: [
  48 + Row(
  49 + children: [
  50 + Text(
  51 + '${title}生日',
  52 + style: TextStyle(
  53 + fontSize: font(16), color: MyColours.color_438E93),
  54 + ),
  55 + Spacer(),
  56 + InkWell(
  57 + onTap: onTapDel,
  58 + child: Padding(
  59 + padding: EdgeInsets.symmetric(horizontal: w(10)),
  60 + child: Image.asset(
  61 + Utils.getImgPath('f_delete_red'),
  62 + width: w(20),
  63 + ),
  64 + )),
  65 + InkWell(
  66 + onTap: onTapEdit,
  67 + child: Padding(
  68 + padding: EdgeInsets.symmetric(horizontal: w(10)),
  69 + child: Image.asset(
  70 + Utils.getImgPath('c_edit'),
  71 + width: w(20),
  72 + ),
  73 + )),
  74 + ],
  75 + ),
  76 + VEmptyView(40),
  77 + Text(
  78 + '(${title})${subTitle}',
  79 + style: TextStyle(fontSize: font(16), color: MyColours.color_000000),
  80 + ),
  81 + VEmptyView(20),
  82 + Padding(
  83 + padding: EdgeInsets.symmetric(horizontal: w(10)),
  84 + child: MyDivider(
  85 + double.infinity,
  86 + w(1),
  87 + color: MyColours.color_F7F7F7,
  88 + ),
  89 + )
  90 + ],
  91 + ),
  92 + );
  93 + }
  94 +
  95 + @override
  96 + Widget build(BuildContext context) {
  97 + customerProvider = Provider.of<CustomerProvider>(context, listen: true);
  98 + return Scaffold(
  99 + appBar: SystemAppBar('客户生日'),
  100 + key: scaffoldKey,
  101 + backgroundColor: MyColours.color_ffffff,
  102 + body: SingleChildScrollView(
  103 + child: Column(
  104 + children: [
  105 + VEmptyView(40),
  106 + _item('公历', '1993年1月3日', onTapDel: () {}, onTapEdit: () {
  107 + DatePicker.showDatePicker(
  108 + context,
  109 + lunarPicker: false,
  110 + showTime: false,
  111 + theme: picker_theme.DatePickerTheme(
  112 + backgroundColor: MyColours.color_ffffff,
  113 + itemStyle: TextStyle(
  114 + color: MyColours.color_438E93, fontSize: font(16)),
  115 + containerHeight: w(220),
  116 + titleHeight: w(58),
  117 + itemHeight: w(44),
  118 + cancelStyle: TextStyle(
  119 + color: MyColours.color_999999, fontSize: font(16)),
  120 + doneStyle: TextStyle(
  121 + color: MyColours.color_438E93, fontSize: font(16))),
  122 + dateInitTime: DateInitTime(
  123 + currentTime: DateTime.now(),
  124 + maxTime: DateTime(2050, 12, 12),
  125 + minTime: DateTime(1900, 1, 1)),
  126 + onConfirm: (time, lunar) {
  127 + debugPrint(time.toString());
  128 + },
  129 + onChanged: (time, lunar) {
  130 + debugPrint("change:${time.toString()}");
  131 + },
  132 + );
  133 +
  134 + // DialogUtil.showPickerDateTime24(
  135 + // context,
  136 + // scaffoldKey,
  137 + // (value) async {
  138 + // // {'text': picker.adapter.text, 'select': selecteds}
  139 + // if (value != null) {
  140 + // setState(() {
  141 + // print(value);
  142 + // birthday = DateUtil.formatDateStr(value,
  143 + // format: DateFormats.y_mo_d);
  144 + // });
  145 + // // 请求接口,设置生日
  146 + // String from = birthday + ' 00:00:00';
  147 + // Map<String, String?> params = {
  148 + // 'id': widget.gid,
  149 + // 'c_day':
  150 + // '${(DateUtil.getDateMsByTimeStr(from)! / 1000).floor()}',
  151 + // };
  152 + // bool sucess = await customerProvider
  153 + // .setGuestInfo(context, params, showLoading: true);
  154 + // if (sucess) {
  155 + // Utils.showToast('保存成功');
  156 + // }
  157 + // }
  158 + // // showDateSelWidget = false;
  159 + // },
  160 + // yearBegin: 1925,
  161 + // minValue: DateTime(1925),
  162 + // dateTime: birthday == ''
  163 + // ? DateTime.now()
  164 + // : DateUtil.getDateTime(birthday),
  165 + // pickerDateTimeType: PickerDateTimeType.kYMD,
  166 + // onCancel: () {
  167 + // // showDateSelWidget = false;
  168 + // });
  169 + }),
  170 + VEmptyView(40),
  171 + _item('农历', '1969年三月廿五', onTapDel: () {}, onTapEdit: () {
  172 + DatePicker.showDatePicker(
  173 + context,
  174 + lunarPicker: true,
  175 + showTime: false,
  176 + theme: picker_theme.DatePickerTheme(
  177 + backgroundColor: MyColours.color_ffffff,
  178 + itemStyle: TextStyle(
  179 + color: MyColours.color_438E93, fontSize: font(16)),
  180 + containerHeight: w(220),
  181 + titleHeight: w(58),
  182 + itemHeight: w(44),
  183 + cancelStyle: TextStyle(
  184 + color: MyColours.color_999999, fontSize: font(16)),
  185 + doneStyle: TextStyle(
  186 + color: MyColours.color_438E93, fontSize: font(16))),
  187 + dateInitTime: DateInitTime(
  188 + currentTime: DateTime.now(),
  189 + maxTime: DateTime(2050, 12, 12),
  190 + minTime: DateTime(1900, 1, 1)),
  191 + onConfirm: (time, lunar) {
  192 + debugPrint(time.toString());
  193 + },
  194 + onChanged: (time, lunar) {
  195 + debugPrint("change:${time.toString()}");
  196 + },
  197 + );
  198 + }),
  199 + ],
  200 + ),
  201 + ));
  202 + }
  203 +}
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 2
3 class MyColours { 3 class MyColours {
  4 + static const Color color_EFEFF0 = Color(0xFFEFEFF0);
4 static const Color color_FFEFC5 = Color(0xFFFFEFC5); 5 static const Color color_FFEFC5 = Color(0xFFFFEFC5);
5 static const Color color_E4461D = Color(0xFFE4461D); 6 static const Color color_E4461D = Color(0xFFE4461D);
6 static const Color color_F8F7F3 = Color(0xFFF8F7F3); 7 static const Color color_F8F7F3 = Color(0xFFF8F7F3);
@@ -2451,4 +2451,27 @@ class NavigatorUtil { @@ -2451,4 +2451,27 @@ class NavigatorUtil {
2451 return _navigateTo(context, "${Routes.enterprise_information_upload_page}", 2451 return _navigateTo(context, "${Routes.enterprise_information_upload_page}",
2452 replace: replace); 2452 replace: replace);
2453 } 2453 }
  2454 +
  2455 +
  2456 +
  2457 +
  2458 +
  2459 +
  2460 +
  2461 +
  2462 + ///客户生日
  2463 + static Future<dynamic> goSetBirthdayPage(
  2464 + BuildContext context,String? gid, {
  2465 + replace = false,
  2466 + }) {
  2467 + return _navigateTo(context, "${Routes.set_birthday_page}?gid=$gid",
  2468 + replace: replace);
  2469 + }
  2470 +
  2471 +
  2472 +
  2473 +
  2474 +
  2475 +
  2476 +
2454 } 2477 }
@@ -70,6 +70,7 @@ import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_ @@ -70,6 +70,7 @@ import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_
70 import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_detail_page_seller.dart'; 70 import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_detail_page_seller.dart';
71 import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_page.dart'; 71 import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_page.dart';
72 import 'package:one_key/pages/my/customer_type/my_customer/my_show_customer_list_page.dart'; 72 import 'package:one_key/pages/my/customer_type/my_customer/my_show_customer_list_page.dart';
  73 +import 'package:one_key/pages/my/customer_type/store_customer/set_birthday_page.dart';
73 import 'package:one_key/pages/my/customer_type/store_customer/show_customer_list_page.dart'; 74 import 'package:one_key/pages/my/customer_type/store_customer/show_customer_list_page.dart';
74 75
75 import 'package:one_key/pages/my/customer_type/store_customer/customer_detail_edit_page.dart'; 76 import 'package:one_key/pages/my/customer_type/store_customer/customer_detail_edit_page.dart';
@@ -2077,13 +2078,14 @@ var couponToPersonnelPageHandle = new Handler( @@ -2077,13 +2078,14 @@ var couponToPersonnelPageHandle = new Handler(
2077 bool onlyShow = 2078 bool onlyShow =
2078 FluroConvertUtils.string2bool(params["onlyShow"]!.first as String); 2079 FluroConvertUtils.string2bool(params["onlyShow"]!.first as String);
2079 2080
  2081 + String id = params["id"]!.first as String;
2080 2082
2081 - String id = params["id"]!.first as String;  
2082 -  
2083 - bool needSave = FluroConvertUtils.string2bool(params["needSave"]!.first as String); 2083 + bool needSave =
  2084 + FluroConvertUtils.string2bool(params["needSave"]!.first as String);
2084 return ChangeNotifierProvider<PersonnelProvider>( 2085 return ChangeNotifierProvider<PersonnelProvider>(
2085 create: (_) => PersonnelProvider(), 2086 create: (_) => PersonnelProvider(),
2086 - child: CouponToPersonnalPage(uids: uids, onlyShow: onlyShow,needSave:needSave,id:id)); 2087 + child: CouponToPersonnalPage(
  2088 + uids: uids, onlyShow: onlyShow, needSave: needSave, id: id));
2087 }); 2089 });
2088 2090
2089 ///宴会----宴会看板 2091 ///宴会----宴会看板
@@ -4223,8 +4225,6 @@ var transactionRecordDetailPageHandle = new Handler( @@ -4223,8 +4225,6 @@ var transactionRecordDetailPageHandle = new Handler(
4223 child: TransactionRecordDetailPage(status: status, id: id)); 4225 child: TransactionRecordDetailPage(status: status, id: id));
4224 }); 4226 });
4225 4227
4226 -  
4227 -  
4228 var depositRecordDetailPageHandle = new Handler( 4228 var depositRecordDetailPageHandle = new Handler(
4229 handlerFunc: (BuildContext? context, Map<String, List<Object>> params) { 4229 handlerFunc: (BuildContext? context, Map<String, List<Object>> params) {
4230 String id = params["id"]!.first as String; 4230 String id = params["id"]!.first as String;
@@ -4239,11 +4239,9 @@ var depositRecordDetailPageHandle = new Handler( @@ -4239,11 +4239,9 @@ var depositRecordDetailPageHandle = new Handler(
4239 // } 4239 // }
4240 4240
4241 return ChangeNotifierProvider<FinanceProvider>( 4241 return ChangeNotifierProvider<FinanceProvider>(
4242 - create: (_) => FinanceProvider(),  
4243 - child: DepositRecordDetailPage( id: id)); 4242 + create: (_) => FinanceProvider(), child: DepositRecordDetailPage(id: id));
4244 }); 4243 });
4245 4244
4246 -  
4247 var vipRecordDetailPageHandle = new Handler( 4245 var vipRecordDetailPageHandle = new Handler(
4248 handlerFunc: (BuildContext? context, Map<String, List<Object>> params) { 4246 handlerFunc: (BuildContext? context, Map<String, List<Object>> params) {
4249 String id = params["id"]!.first as String; 4247 String id = params["id"]!.first as String;
@@ -4258,15 +4256,25 @@ var vipRecordDetailPageHandle = new Handler( @@ -4258,15 +4256,25 @@ var vipRecordDetailPageHandle = new Handler(
4258 // } 4256 // }
4259 4257
4260 return ChangeNotifierProvider<FinanceProvider>( 4258 return ChangeNotifierProvider<FinanceProvider>(
4261 - create: (_) => FinanceProvider(),  
4262 - child:VipRecordDetailPage(id: id)); 4259 + create: (_) => FinanceProvider(), child: VipRecordDetailPage(id: id));
4263 }); 4260 });
4264 4261
  4262 +var setBirthdayPageHandle = new Handler(
  4263 + handlerFunc: (BuildContext? context, Map<String, List<Object>> params) {
  4264 + String? gid = params["gid"]!.first as String;
  4265 + // String status = params["status"]!.first as String;
  4266 + // bool isMine =
  4267 + // FluroConvertUtils.string2bool(params["isMine"]!.first as String);
  4268 + // CouponSunModel? couponSunModel;
  4269 + // if (params.keys.contains("couponSunModel")) {
  4270 + // couponSunModel = CouponSunModel.fromJson(json.decode(
  4271 + // FluroConvertUtils.fluroCnParamsDecode(
  4272 + // params["couponSunModel"]!.first as String)));
  4273 + // }
4265 4274
4266 -  
4267 -  
4268 -  
4269 - 4275 + return ChangeNotifierProvider<CustomerProvider>(
  4276 + create: (_) => CustomerProvider(), child: SetBirthdayPage(gid:gid));
  4277 +});
4270 4278
4271 ///支付返券 4279 ///支付返券
4272 var paymentGiftPageHandle = new Handler( 4280 var paymentGiftPageHandle = new Handler(
@@ -415,28 +415,19 @@ class Routes { @@ -415,28 +415,19 @@ class Routes {
415 static String transaction_record_detail_page = 415 static String transaction_record_detail_page =
416 "/transaction_record_detail_page"; //订单消费详情 416 "/transaction_record_detail_page"; //订单消费详情
417 417
418 -  
419 -  
420 - static String payment_gift_page =  
421 - "/payment_gift_page"; //支付返券  
422 - static String payment_gift_select_page = 418 + static String payment_gift_page = "/payment_gift_page"; //支付返券
  419 + static String payment_gift_select_page =
423 "/payment_gift_select_page"; //支付返券选择券页面(免费代金券) 420 "/payment_gift_select_page"; //支付返券选择券页面(免费代金券)
424 421
425 - static String enterprise_information_upload_page = 422 + static String enterprise_information_upload_page =
426 "/enterprise_information_upload_page"; //企业客户资料上传页面 423 "/enterprise_information_upload_page"; //企业客户资料上传页面
427 424
428 -  
429 - static String deposit_record_detail_page = 425 + static String deposit_record_detail_page =
430 "/deposit_record_detail_page"; //预订订金详情页 426 "/deposit_record_detail_page"; //预订订金详情页
431 427
432 - static String vip_record_detail_page=  
433 - "/vip_record_detail_page"; //会员充值订单详情页  
434 - 428 + static String vip_record_detail_page = "/vip_record_detail_page"; //会员充值订单详情页
435 429
436 -  
437 -  
438 -  
439 - 430 + static String set_birthday_page = "/set_birthday_page"; //客户生日
440 431
441 static void configureRoutes(FluroRouter router) { 432 static void configureRoutes(FluroRouter router) {
442 router.notFoundHandler = new Handler( 433 router.notFoundHandler = new Handler(
@@ -803,37 +794,24 @@ class Routes { @@ -803,37 +794,24 @@ class Routes {
803 794
804 router.define(transaction_record_home_page, 795 router.define(transaction_record_home_page,
805 handler: transactionRecordHomePageHandle); 796 handler: transactionRecordHomePageHandle);
806 - router.define(transaction_record_search_page,  
807 - handler: transactionRecordSearchPageHandle);  
808 - router.define(transaction_record_detail_page, 797 + router.define(transaction_record_search_page,
  798 + handler: transactionRecordSearchPageHandle);
  799 + router.define(transaction_record_detail_page,
809 handler: transactionRecordDetailPageHandle); 800 handler: transactionRecordDetailPageHandle);
810 - router.define(payment_gift_page,  
811 - handler: paymentGiftPageHandle);  
812 - router.define(payment_gift_select_page,  
813 - handler:paymentGiftSelectPageHandle);  
814 -  
815 - router.define(enterprise_information_upload_page,  
816 - handler:enterpriseInformationUploadPageHandle);  
817 -  
818 -  
819 -  
820 - router.define(deposit_record_detail_page,  
821 - handler:depositRecordDetailPageHandle);  
822 -  
823 - router.define(vip_record_detail_page,  
824 - handler:vipRecordDetailPageHandle);  
825 - 801 + router.define(payment_gift_page, handler: paymentGiftPageHandle);
  802 + router.define(payment_gift_select_page,
  803 + handler: paymentGiftSelectPageHandle);
826 804
827 - 805 + router.define(enterprise_information_upload_page,
  806 + handler: enterpriseInformationUploadPageHandle);
828 807
  808 + router.define(deposit_record_detail_page,
  809 + handler: depositRecordDetailPageHandle);
829 810
830 - 811 + router.define(vip_record_detail_page, handler: vipRecordDetailPageHandle);
831 812
832 - 813 + router.define(set_birthday_page, handler: setBirthdayPageHandle);
833 814
834 -  
835 -  
836 -  
837 - 815 +
838 } 816 }
839 } 817 }
@@ -12057,7 +12057,7 @@ class DialogUtil { @@ -12057,7 +12057,7 @@ class DialogUtil {
12057 onTap: () { 12057 onTap: () {
12058 FocusScope.of(context).requestFocus( 12058 FocusScope.of(context).requestFocus(
12059 FocusNode()); //点击空白处隐藏键盘 12059 FocusNode()); //点击空白处隐藏键盘
12060 - incrementCounterYear( 12060 + incrementCounterYear(
12061 context, 12061 context,
12062 gongli, 12062 gongli,
12063 yearStr == '选填' 12063 yearStr == '选填'
  1 +## 1.0.1
  2 +
  3 +* Flutter Solar + lunar time selector
  4 +
  5 +## 1.0.2
  6 +
  7 +* [fix] Lunar callback.
  8 +
  9 +## 1.0.3
  10 +
  11 +* [add] show time check.
  12 +
  13 +## 1.0.4
  14 +
  15 +* [fix] The lunar leap month caused the switch from the Gregorian calendar to the Gregorian calendar, incorrect.
  16 +
  17 +
  18 +## 1.0.5
  19 +* [fix] There is a leap month in the current year, and the leap month is less than the current month, resulting in the switching from the Gregorian calendar to the solar calendar, which is incorrect.
  20 +* [add] Suitable for Flutter 3.x version.
  21 +
  22 +## 1.0.6
  23 +* [add] Lunar type show lunar year.
  1 +MIT License
  2 +
  3 +Copyright (c) 2022 周枇杷!
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 +SOFTWARE.
  1 +## Flutter 农历日期选择器
  2 +
  3 +| 阳历显示 | 阴历显示 |
  4 +| -------------------- | -------------------------------- |
  5 +| ![](screen_date_time.png) | ![](screen_lunar_date_time.png) | ![](screen_datetime_chinese.png) |
  6 +
  7 +
  8 +## 引用
  9 +``` yaml
  10 +flutter_lunar_datetime_picker: ^last_version
  11 +```
  12 +
  13 +
  14 +## 使用
  15 +
  16 +``` dart
  17 +DatePicker.showDatePicker(
  18 + context,
  19 + lunarPicker: false,
  20 + dateInitTime: DateInitTime(
  21 + currentTime: DateTime.now(),
  22 + maxTime: DateTime(2026, 12, 12),
  23 + minTime: DateTime(2018, 3, 4)),
  24 + onConfirm: (time) {
  25 + debugPrint(time.toString());
  26 + },
  27 + onChanged: (time) {
  28 + debugPrint("change:${time.toString()}");
  29 + },
  30 + );
  31 +```
  32 +
  33 +## 感谢
  34 +- [flutter_datetime_picker](https://github.com/Realank/flutter_datetime_picker) 提供PickerView方案
  35 +
  36 +- [lunar_flutter](https://github.com/6tail/lunar-flutter) 提供农历日期算法
  1 +include: package:flutter_lints/flutter.yaml
  2 +
  3 +# Additional information about this file can be found at
  4 +# https://dart.dev/guides/language/analysis-options
  1 +# example
  2 +
  3 +A new Flutter project.
  4 +
  5 +## Getting Started
  6 +
  7 +This project is a starting point for a Flutter application.
  8 +
  9 +A few resources to get you started if this is your first Flutter project:
  10 +
  11 +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
  12 +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
  13 +
  14 +For help getting started with Flutter development, view the
  15 +[online documentation](https://docs.flutter.dev/), which offers tutorials,
  16 +samples, guidance on mobile development, and a full API reference.
  1 +# This file configures the analyzer, which statically analyzes Dart code to
  2 +# check for errors, warnings, and lints.
  3 +#
  4 +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
  5 +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
  6 +# invoked from the command line by running `flutter analyze`.
  7 +
  8 +# The following line activates a set of recommended lints for Flutter apps,
  9 +# packages, and plugins designed to encourage good coding practices.
  10 +include: package:flutter_lints/flutter.yaml
  11 +
  12 +linter:
  13 + # The lint rules applied to this project can be customized in the
  14 + # section below to disable rules from the `package:flutter_lints/flutter.yaml`
  15 + # included above or to enable additional rules. A list of all available lints
  16 + # and their documentation is published at
  17 + # https://dart-lang.github.io/linter/lints/index.html.
  18 + #
  19 + # Instead of disabling a lint rule for the entire project in the
  20 + # section below, it can also be suppressed for a single line of code
  21 + # or a specific dart file by using the `// ignore: name_of_lint` and
  22 + # `// ignore_for_file: name_of_lint` syntax on the line or in the file
  23 + # producing the lint.
  24 + rules:
  25 + # avoid_print: false # Uncomment to disable the `avoid_print` rule
  26 + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
  27 +
  28 +# Additional information about this file can be found at
  29 +# https://dart.dev/guides/language/analysis-options
  1 +def localProperties = new Properties()
  2 +def localPropertiesFile = rootProject.file('local.properties')
  3 +if (localPropertiesFile.exists()) {
  4 + localPropertiesFile.withReader('UTF-8') { reader ->
  5 + localProperties.load(reader)
  6 + }
  7 +}
  8 +
  9 +def flutterRoot = localProperties.getProperty('flutter.sdk')
  10 +if (flutterRoot == null) {
  11 + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
  12 +}
  13 +
  14 +def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
  15 +if (flutterVersionCode == null) {
  16 + flutterVersionCode = '1'
  17 +}
  18 +
  19 +def flutterVersionName = localProperties.getProperty('flutter.versionName')
  20 +if (flutterVersionName == null) {
  21 + flutterVersionName = '1.0'
  22 +}
  23 +
  24 +apply plugin: 'com.android.application'
  25 +apply plugin: 'kotlin-android'
  26 +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
  27 +
  28 +android {
  29 + compileSdkVersion flutter.compileSdkVersion
  30 + ndkVersion flutter.ndkVersion
  31 +
  32 + compileOptions {
  33 + sourceCompatibility JavaVersion.VERSION_1_8
  34 + targetCompatibility JavaVersion.VERSION_1_8
  35 + }
  36 +
  37 + kotlinOptions {
  38 + jvmTarget = '1.8'
  39 + }
  40 +
  41 + sourceSets {
  42 + main.java.srcDirs += 'src/main/kotlin'
  43 + }
  44 +
  45 + defaultConfig {
  46 + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
  47 + applicationId "com.loquatz.example.example"
  48 + // You can update the following values to match your application needs.
  49 + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
  50 + minSdkVersion flutter.minSdkVersion
  51 + targetSdkVersion flutter.targetSdkVersion
  52 + versionCode flutterVersionCode.toInteger()
  53 + versionName flutterVersionName
  54 + }
  55 +
  56 + buildTypes {
  57 + release {
  58 + // TODO: Add your own signing config for the release build.
  59 + // Signing with the debug keys for now, so `flutter run --release` works.
  60 + signingConfig signingConfigs.debug
  61 + }
  62 + }
  63 +}
  64 +
  65 +flutter {
  66 + source '../..'
  67 +}
  68 +
  69 +dependencies {
  70 + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
  71 +}
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.loquatz.example.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + the Flutter tool needs it to communicate with the running application
  5 + to allow setting breakpoints, to provide hot reload, etc.
  6 + -->
  7 + <uses-permission android:name="android.permission.INTERNET"/>
  8 +</manifest>
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.loquatz.example.example">
  3 + <application
  4 + android:label="example"
  5 + android:name="${applicationName}"
  6 + android:icon="@mipmap/ic_launcher">
  7 + <activity
  8 + android:name=".MainActivity"
  9 + android:exported="true"
  10 + android:launchMode="singleTop"
  11 + android:theme="@style/LaunchTheme"
  12 + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
  13 + android:hardwareAccelerated="true"
  14 + android:windowSoftInputMode="adjustResize">
  15 + <!-- Specifies an Android theme to apply to this Activity as soon as
  16 + the Android process has started. This theme is visible to the user
  17 + while the Flutter UI initializes. After that, this theme continues
  18 + to determine the Window background behind the Flutter UI. -->
  19 + <meta-data
  20 + android:name="io.flutter.embedding.android.NormalTheme"
  21 + android:resource="@style/NormalTheme"
  22 + />
  23 + <intent-filter>
  24 + <action android:name="android.intent.action.MAIN"/>
  25 + <category android:name="android.intent.category.LAUNCHER"/>
  26 + </intent-filter>
  27 + </activity>
  28 + <!-- Don't delete the meta-data below.
  29 + This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
  30 + <meta-data
  31 + android:name="flutterEmbedding"
  32 + android:value="2" />
  33 + </application>
  34 +</manifest>
  1 +package io.flutter.plugins;
  2 +
  3 +import androidx.annotation.Keep;
  4 +import androidx.annotation.NonNull;
  5 +import io.flutter.Log;
  6 +
  7 +import io.flutter.embedding.engine.FlutterEngine;
  8 +
  9 +/**
  10 + * Generated file. Do not edit.
  11 + * This file is generated by the Flutter tool based on the
  12 + * plugins that support the Android platform.
  13 + */
  14 +@Keep
  15 +public final class GeneratedPluginRegistrant {
  16 + private static final String TAG = "GeneratedPluginRegistrant";
  17 + public static void registerWith(@NonNull FlutterEngine flutterEngine) {
  18 + }
  19 +}
  1 +package com.loquatz.example.example
  2 +
  3 +import io.flutter.embedding.android.FlutterActivity
  4 +
  5 +class MainActivity: FlutterActivity() {
  6 +}
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<!-- Modify this file to customize your launch splash screen -->
  3 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  4 + <item android:drawable="?android:colorBackground" />
  5 +
  6 + <!-- You can insert your own image assets here -->
  7 + <!-- <item>
  8 + <bitmap
  9 + android:gravity="center"
  10 + android:src="@mipmap/launch_image" />
  11 + </item> -->
  12 +</layer-list>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<!-- Modify this file to customize your launch splash screen -->
  3 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  4 + <item android:drawable="@android:color/white" />
  5 +
  6 + <!-- You can insert your own image assets here -->
  7 + <!-- <item>
  8 + <bitmap
  9 + android:gravity="center"
  10 + android:src="@mipmap/launch_image" />
  11 + </item> -->
  12 +</layer-list>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
  4 + <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
  5 + <!-- Show a splash screen on the activity. Automatically removed when
  6 + the Flutter engine draws its first frame -->
  7 + <item name="android:windowBackground">@drawable/launch_background</item>
  8 + </style>
  9 + <!-- Theme applied to the Android Window as soon as the process has started.
  10 + This theme determines the color of the Android Window while your
  11 + Flutter UI initializes, as well as behind your Flutter UI while its
  12 + running.
  13 +
  14 + This Theme is only used starting with V2 of Flutter's Android embedding. -->
  15 + <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
  16 + <item name="android:windowBackground">?android:colorBackground</item>
  17 + </style>
  18 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
  4 + <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
  5 + <!-- Show a splash screen on the activity. Automatically removed when
  6 + the Flutter engine draws its first frame -->
  7 + <item name="android:windowBackground">@drawable/launch_background</item>
  8 + </style>
  9 + <!-- Theme applied to the Android Window as soon as the process has started.
  10 + This theme determines the color of the Android Window while your
  11 + Flutter UI initializes, as well as behind your Flutter UI while its
  12 + running.
  13 +
  14 + This Theme is only used starting with V2 of Flutter's Android embedding. -->
  15 + <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
  16 + <item name="android:windowBackground">?android:colorBackground</item>
  17 + </style>
  18 +</resources>
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.loquatz.example.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + the Flutter tool needs it to communicate with the running application
  5 + to allow setting breakpoints, to provide hot reload, etc.
  6 + -->
  7 + <uses-permission android:name="android.permission.INTERNET"/>
  8 +</manifest>
  1 +buildscript {
  2 + ext.kotlin_version = '1.7.10'
  3 + repositories {
  4 + google()
  5 + mavenCentral()
  6 + }
  7 +
  8 + dependencies {
  9 + classpath 'com.android.tools.build:gradle:7.1.2'
  10 + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  11 + }
  12 +}
  13 +
  14 +allprojects {
  15 + repositories {
  16 + google()
  17 + mavenCentral()
  18 + }
  19 +}
  20 +
  21 +rootProject.buildDir = '../build'
  22 +subprojects {
  23 + project.buildDir = "${rootProject.buildDir}/${project.name}"
  24 +}
  25 +subprojects {
  26 + project.evaluationDependsOn(':app')
  27 +}
  28 +
  29 +tasks.register("clean", Delete) {
  30 + delete rootProject.buildDir
  31 +}
  1 +org.gradle.jvmargs=-Xmx1536M
  2 +android.useAndroidX=true
  3 +android.enableJetifier=true
  1 +distributionBase=GRADLE_USER_HOME
  2 +distributionPath=wrapper/dists
  3 +zipStoreBase=GRADLE_USER_HOME
  4 +zipStorePath=wrapper/dists
  5 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
  1 +sdk.dir=/Users/wangdongni/Library/Android/sdk
  2 +flutter.sdk=/Users/wangdongni/fvm/versions/3.27.3
  1 +include ':app'
  2 +
  3 +def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
  4 +def properties = new Properties()
  5 +
  6 +assert localPropertiesFile.exists()
  7 +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
  8 +
  9 +def flutterSdkPath = properties.getProperty("flutter.sdk")
  10 +assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
  11 +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>en</string>
  7 + <key>CFBundleExecutable</key>
  8 + <string>App</string>
  9 + <key>CFBundleIdentifier</key>
  10 + <string>io.flutter.flutter.app</string>
  11 + <key>CFBundleInfoDictionaryVersion</key>
  12 + <string>6.0</string>
  13 + <key>CFBundleName</key>
  14 + <string>App</string>
  15 + <key>CFBundlePackageType</key>
  16 + <string>FMWK</string>
  17 + <key>CFBundleShortVersionString</key>
  18 + <string>1.0</string>
  19 + <key>CFBundleSignature</key>
  20 + <string>????</string>
  21 + <key>CFBundleVersion</key>
  22 + <string>1.0</string>
  23 + <key>MinimumOSVersion</key>
  24 + <string>11.0</string>
  25 +</dict>
  26 +</plist>
  1 +// This is a generated file; do not edit or check into version control.
  2 +FLUTTER_ROOT=/Users/wangdongni/fvm/versions/3.27.3
  3 +FLUTTER_APPLICATION_PATH=/Users/wangdongni/Desktop/Flutter-ReserveApp/library/flutter_lunar_datetime_picker-1.0.6/example
  4 +COCOAPODS_PARALLEL_CODE_SIGN=true
  5 +FLUTTER_TARGET=lib/main.dart
  6 +FLUTTER_BUILD_DIR=build
  7 +FLUTTER_BUILD_NAME=1.0.0
  8 +FLUTTER_BUILD_NUMBER=1
  9 +EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
  10 +EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
  11 +DART_OBFUSCATION=false
  12 +TRACK_WIDGET_CREATION=true
  13 +TREE_SHAKE_ICONS=false
  14 +PACKAGE_CONFIG=.dart_tool/package_config.json
  1 +#!/bin/sh
  2 +# This is a generated file; do not edit or check into version control.
  3 +export "FLUTTER_ROOT=/Users/wangdongni/fvm/versions/3.27.3"
  4 +export "FLUTTER_APPLICATION_PATH=/Users/wangdongni/Desktop/Flutter-ReserveApp/library/flutter_lunar_datetime_picker-1.0.6/example"
  5 +export "COCOAPODS_PARALLEL_CODE_SIGN=true"
  6 +export "FLUTTER_TARGET=lib/main.dart"
  7 +export "FLUTTER_BUILD_DIR=build"
  8 +export "FLUTTER_BUILD_NAME=1.0.0"
  9 +export "FLUTTER_BUILD_NUMBER=1"
  10 +export "DART_OBFUSCATION=false"
  11 +export "TRACK_WIDGET_CREATION=true"
  12 +export "TREE_SHAKE_ICONS=false"
  13 +export "PACKAGE_CONFIG=.dart_tool/package_config.json"
  1 +// !$*UTF8*$!
  2 +{
  3 + archiveVersion = 1;
  4 + classes = {
  5 + };
  6 + objectVersion = 50;
  7 + objects = {
  8 +
  9 +/* Begin PBXBuildFile section */
  10 + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
  11 + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
  12 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
  13 + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
  14 + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
  15 + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
  16 +/* End PBXBuildFile section */
  17 +
  18 +/* Begin PBXCopyFilesBuildPhase section */
  19 + 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
  20 + isa = PBXCopyFilesBuildPhase;
  21 + buildActionMask = 2147483647;
  22 + dstPath = "";
  23 + dstSubfolderSpec = 10;
  24 + files = (
  25 + );
  26 + name = "Embed Frameworks";
  27 + runOnlyForDeploymentPostprocessing = 0;
  28 + };
  29 +/* End PBXCopyFilesBuildPhase section */
  30 +
  31 +/* Begin PBXFileReference section */
  32 + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
  33 + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
  34 + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
  35 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
  36 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
  37 + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
  38 + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
  39 + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
  40 + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
  41 + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
  42 + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
  43 + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
  44 + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
  45 +/* End PBXFileReference section */
  46 +
  47 +/* Begin PBXFrameworksBuildPhase section */
  48 + 97C146EB1CF9000F007C117D /* Frameworks */ = {
  49 + isa = PBXFrameworksBuildPhase;
  50 + buildActionMask = 2147483647;
  51 + files = (
  52 + );
  53 + runOnlyForDeploymentPostprocessing = 0;
  54 + };
  55 +/* End PBXFrameworksBuildPhase section */
  56 +
  57 +/* Begin PBXGroup section */
  58 + 9740EEB11CF90186004384FC /* Flutter */ = {
  59 + isa = PBXGroup;
  60 + children = (
  61 + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
  62 + 9740EEB21CF90195004384FC /* Debug.xcconfig */,
  63 + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
  64 + 9740EEB31CF90195004384FC /* Generated.xcconfig */,
  65 + );
  66 + name = Flutter;
  67 + sourceTree = "<group>";
  68 + };
  69 + 97C146E51CF9000F007C117D = {
  70 + isa = PBXGroup;
  71 + children = (
  72 + 9740EEB11CF90186004384FC /* Flutter */,
  73 + 97C146F01CF9000F007C117D /* Runner */,
  74 + 97C146EF1CF9000F007C117D /* Products */,
  75 + );
  76 + sourceTree = "<group>";
  77 + };
  78 + 97C146EF1CF9000F007C117D /* Products */ = {
  79 + isa = PBXGroup;
  80 + children = (
  81 + 97C146EE1CF9000F007C117D /* Runner.app */,
  82 + );
  83 + name = Products;
  84 + sourceTree = "<group>";
  85 + };
  86 + 97C146F01CF9000F007C117D /* Runner */ = {
  87 + isa = PBXGroup;
  88 + children = (
  89 + 97C146FA1CF9000F007C117D /* Main.storyboard */,
  90 + 97C146FD1CF9000F007C117D /* Assets.xcassets */,
  91 + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
  92 + 97C147021CF9000F007C117D /* Info.plist */,
  93 + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
  94 + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
  95 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
  96 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
  97 + );
  98 + path = Runner;
  99 + sourceTree = "<group>";
  100 + };
  101 +/* End PBXGroup section */
  102 +
  103 +/* Begin PBXNativeTarget section */
  104 + 97C146ED1CF9000F007C117D /* Runner */ = {
  105 + isa = PBXNativeTarget;
  106 + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
  107 + buildPhases = (
  108 + 9740EEB61CF901F6004384FC /* Run Script */,
  109 + 97C146EA1CF9000F007C117D /* Sources */,
  110 + 97C146EB1CF9000F007C117D /* Frameworks */,
  111 + 97C146EC1CF9000F007C117D /* Resources */,
  112 + 9705A1C41CF9048500538489 /* Embed Frameworks */,
  113 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
  114 + );
  115 + buildRules = (
  116 + );
  117 + dependencies = (
  118 + );
  119 + name = Runner;
  120 + productName = Runner;
  121 + productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
  122 + productType = "com.apple.product-type.application";
  123 + };
  124 +/* End PBXNativeTarget section */
  125 +
  126 +/* Begin PBXProject section */
  127 + 97C146E61CF9000F007C117D /* Project object */ = {
  128 + isa = PBXProject;
  129 + attributes = {
  130 + LastUpgradeCheck = 1300;
  131 + ORGANIZATIONNAME = "";
  132 + TargetAttributes = {
  133 + 97C146ED1CF9000F007C117D = {
  134 + CreatedOnToolsVersion = 7.3.1;
  135 + LastSwiftMigration = 1100;
  136 + };
  137 + };
  138 + };
  139 + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
  140 + compatibilityVersion = "Xcode 9.3";
  141 + developmentRegion = en;
  142 + hasScannedForEncodings = 0;
  143 + knownRegions = (
  144 + en,
  145 + Base,
  146 + );
  147 + mainGroup = 97C146E51CF9000F007C117D;
  148 + productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
  149 + projectDirPath = "";
  150 + projectRoot = "";
  151 + targets = (
  152 + 97C146ED1CF9000F007C117D /* Runner */,
  153 + );
  154 + };
  155 +/* End PBXProject section */
  156 +
  157 +/* Begin PBXResourcesBuildPhase section */
  158 + 97C146EC1CF9000F007C117D /* Resources */ = {
  159 + isa = PBXResourcesBuildPhase;
  160 + buildActionMask = 2147483647;
  161 + files = (
  162 + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
  163 + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
  164 + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
  165 + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
  166 + );
  167 + runOnlyForDeploymentPostprocessing = 0;
  168 + };
  169 +/* End PBXResourcesBuildPhase section */
  170 +
  171 +/* Begin PBXShellScriptBuildPhase section */
  172 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
  173 + isa = PBXShellScriptBuildPhase;
  174 + buildActionMask = 2147483647;
  175 + files = (
  176 + );
  177 + inputPaths = (
  178 + );
  179 + name = "Thin Binary";
  180 + outputPaths = (
  181 + );
  182 + runOnlyForDeploymentPostprocessing = 0;
  183 + shellPath = /bin/sh;
  184 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
  185 + };
  186 + 9740EEB61CF901F6004384FC /* Run Script */ = {
  187 + isa = PBXShellScriptBuildPhase;
  188 + buildActionMask = 2147483647;
  189 + files = (
  190 + );
  191 + inputPaths = (
  192 + );
  193 + name = "Run Script";
  194 + outputPaths = (
  195 + );
  196 + runOnlyForDeploymentPostprocessing = 0;
  197 + shellPath = /bin/sh;
  198 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
  199 + };
  200 +/* End PBXShellScriptBuildPhase section */
  201 +
  202 +/* Begin PBXSourcesBuildPhase section */
  203 + 97C146EA1CF9000F007C117D /* Sources */ = {
  204 + isa = PBXSourcesBuildPhase;
  205 + buildActionMask = 2147483647;
  206 + files = (
  207 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
  208 + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
  209 + );
  210 + runOnlyForDeploymentPostprocessing = 0;
  211 + };
  212 +/* End PBXSourcesBuildPhase section */
  213 +
  214 +/* Begin PBXVariantGroup section */
  215 + 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
  216 + isa = PBXVariantGroup;
  217 + children = (
  218 + 97C146FB1CF9000F007C117D /* Base */,
  219 + );
  220 + name = Main.storyboard;
  221 + sourceTree = "<group>";
  222 + };
  223 + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
  224 + isa = PBXVariantGroup;
  225 + children = (
  226 + 97C147001CF9000F007C117D /* Base */,
  227 + );
  228 + name = LaunchScreen.storyboard;
  229 + sourceTree = "<group>";
  230 + };
  231 +/* End PBXVariantGroup section */
  232 +
  233 +/* Begin XCBuildConfiguration section */
  234 + 249021D3217E4FDB00AE95B9 /* Profile */ = {
  235 + isa = XCBuildConfiguration;
  236 + buildSettings = {
  237 + ALWAYS_SEARCH_USER_PATHS = NO;
  238 + CLANG_ANALYZER_NONNULL = YES;
  239 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  240 + CLANG_CXX_LIBRARY = "libc++";
  241 + CLANG_ENABLE_MODULES = YES;
  242 + CLANG_ENABLE_OBJC_ARC = YES;
  243 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  244 + CLANG_WARN_BOOL_CONVERSION = YES;
  245 + CLANG_WARN_COMMA = YES;
  246 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  247 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  248 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  249 + CLANG_WARN_EMPTY_BODY = YES;
  250 + CLANG_WARN_ENUM_CONVERSION = YES;
  251 + CLANG_WARN_INFINITE_RECURSION = YES;
  252 + CLANG_WARN_INT_CONVERSION = YES;
  253 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  254 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  255 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  256 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  257 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  258 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  259 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  260 + CLANG_WARN_UNREACHABLE_CODE = YES;
  261 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  262 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  263 + COPY_PHASE_STRIP = NO;
  264 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  265 + ENABLE_NS_ASSERTIONS = NO;
  266 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  267 + GCC_C_LANGUAGE_STANDARD = gnu99;
  268 + GCC_NO_COMMON_BLOCKS = YES;
  269 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  270 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  271 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  272 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  273 + GCC_WARN_UNUSED_FUNCTION = YES;
  274 + GCC_WARN_UNUSED_VARIABLE = YES;
  275 + IPHONEOS_DEPLOYMENT_TARGET = 11.0;
  276 + MTL_ENABLE_DEBUG_INFO = NO;
  277 + SDKROOT = iphoneos;
  278 + SUPPORTED_PLATFORMS = iphoneos;
  279 + TARGETED_DEVICE_FAMILY = "1,2";
  280 + VALIDATE_PRODUCT = YES;
  281 + };
  282 + name = Profile;
  283 + };
  284 + 249021D4217E4FDB00AE95B9 /* Profile */ = {
  285 + isa = XCBuildConfiguration;
  286 + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
  287 + buildSettings = {
  288 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  289 + CLANG_ENABLE_MODULES = YES;
  290 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  291 + ENABLE_BITCODE = NO;
  292 + INFOPLIST_FILE = Runner/Info.plist;
  293 + LD_RUNPATH_SEARCH_PATHS = (
  294 + "$(inherited)",
  295 + "@executable_path/Frameworks",
  296 + );
  297 + PRODUCT_BUNDLE_IDENTIFIER = com.loquatz.example.example;
  298 + PRODUCT_NAME = "$(TARGET_NAME)";
  299 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  300 + SWIFT_VERSION = 5.0;
  301 + VERSIONING_SYSTEM = "apple-generic";
  302 + };
  303 + name = Profile;
  304 + };
  305 + 97C147031CF9000F007C117D /* Debug */ = {
  306 + isa = XCBuildConfiguration;
  307 + buildSettings = {
  308 + ALWAYS_SEARCH_USER_PATHS = NO;
  309 + CLANG_ANALYZER_NONNULL = YES;
  310 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  311 + CLANG_CXX_LIBRARY = "libc++";
  312 + CLANG_ENABLE_MODULES = YES;
  313 + CLANG_ENABLE_OBJC_ARC = YES;
  314 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  315 + CLANG_WARN_BOOL_CONVERSION = YES;
  316 + CLANG_WARN_COMMA = YES;
  317 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  318 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  319 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  320 + CLANG_WARN_EMPTY_BODY = YES;
  321 + CLANG_WARN_ENUM_CONVERSION = YES;
  322 + CLANG_WARN_INFINITE_RECURSION = YES;
  323 + CLANG_WARN_INT_CONVERSION = YES;
  324 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  325 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  326 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  327 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  328 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  329 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  330 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  331 + CLANG_WARN_UNREACHABLE_CODE = YES;
  332 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  333 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  334 + COPY_PHASE_STRIP = NO;
  335 + DEBUG_INFORMATION_FORMAT = dwarf;
  336 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  337 + ENABLE_TESTABILITY = YES;
  338 + GCC_C_LANGUAGE_STANDARD = gnu99;
  339 + GCC_DYNAMIC_NO_PIC = NO;
  340 + GCC_NO_COMMON_BLOCKS = YES;
  341 + GCC_OPTIMIZATION_LEVEL = 0;
  342 + GCC_PREPROCESSOR_DEFINITIONS = (
  343 + "DEBUG=1",
  344 + "$(inherited)",
  345 + );
  346 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  347 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  348 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  349 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  350 + GCC_WARN_UNUSED_FUNCTION = YES;
  351 + GCC_WARN_UNUSED_VARIABLE = YES;
  352 + IPHONEOS_DEPLOYMENT_TARGET = 11.0;
  353 + MTL_ENABLE_DEBUG_INFO = YES;
  354 + ONLY_ACTIVE_ARCH = YES;
  355 + SDKROOT = iphoneos;
  356 + TARGETED_DEVICE_FAMILY = "1,2";
  357 + };
  358 + name = Debug;
  359 + };
  360 + 97C147041CF9000F007C117D /* Release */ = {
  361 + isa = XCBuildConfiguration;
  362 + buildSettings = {
  363 + ALWAYS_SEARCH_USER_PATHS = NO;
  364 + CLANG_ANALYZER_NONNULL = YES;
  365 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  366 + CLANG_CXX_LIBRARY = "libc++";
  367 + CLANG_ENABLE_MODULES = YES;
  368 + CLANG_ENABLE_OBJC_ARC = YES;
  369 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  370 + CLANG_WARN_BOOL_CONVERSION = YES;
  371 + CLANG_WARN_COMMA = YES;
  372 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  373 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  374 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  375 + CLANG_WARN_EMPTY_BODY = YES;
  376 + CLANG_WARN_ENUM_CONVERSION = YES;
  377 + CLANG_WARN_INFINITE_RECURSION = YES;
  378 + CLANG_WARN_INT_CONVERSION = YES;
  379 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  380 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  381 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  382 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  383 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  384 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  385 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  386 + CLANG_WARN_UNREACHABLE_CODE = YES;
  387 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  388 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  389 + COPY_PHASE_STRIP = NO;
  390 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  391 + ENABLE_NS_ASSERTIONS = NO;
  392 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  393 + GCC_C_LANGUAGE_STANDARD = gnu99;
  394 + GCC_NO_COMMON_BLOCKS = YES;
  395 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  396 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  397 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  398 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  399 + GCC_WARN_UNUSED_FUNCTION = YES;
  400 + GCC_WARN_UNUSED_VARIABLE = YES;
  401 + IPHONEOS_DEPLOYMENT_TARGET = 11.0;
  402 + MTL_ENABLE_DEBUG_INFO = NO;
  403 + SDKROOT = iphoneos;
  404 + SUPPORTED_PLATFORMS = iphoneos;
  405 + SWIFT_COMPILATION_MODE = wholemodule;
  406 + SWIFT_OPTIMIZATION_LEVEL = "-O";
  407 + TARGETED_DEVICE_FAMILY = "1,2";
  408 + VALIDATE_PRODUCT = YES;
  409 + };
  410 + name = Release;
  411 + };
  412 + 97C147061CF9000F007C117D /* Debug */ = {
  413 + isa = XCBuildConfiguration;
  414 + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
  415 + buildSettings = {
  416 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  417 + CLANG_ENABLE_MODULES = YES;
  418 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  419 + ENABLE_BITCODE = NO;
  420 + INFOPLIST_FILE = Runner/Info.plist;
  421 + LD_RUNPATH_SEARCH_PATHS = (
  422 + "$(inherited)",
  423 + "@executable_path/Frameworks",
  424 + );
  425 + PRODUCT_BUNDLE_IDENTIFIER = com.loquatz.example.example;
  426 + PRODUCT_NAME = "$(TARGET_NAME)";
  427 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  428 + SWIFT_OPTIMIZATION_LEVEL = "-Onone";
  429 + SWIFT_VERSION = 5.0;
  430 + VERSIONING_SYSTEM = "apple-generic";
  431 + };
  432 + name = Debug;
  433 + };
  434 + 97C147071CF9000F007C117D /* Release */ = {
  435 + isa = XCBuildConfiguration;
  436 + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
  437 + buildSettings = {
  438 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  439 + CLANG_ENABLE_MODULES = YES;
  440 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  441 + ENABLE_BITCODE = NO;
  442 + INFOPLIST_FILE = Runner/Info.plist;
  443 + LD_RUNPATH_SEARCH_PATHS = (
  444 + "$(inherited)",
  445 + "@executable_path/Frameworks",
  446 + );
  447 + PRODUCT_BUNDLE_IDENTIFIER = com.loquatz.example.example;
  448 + PRODUCT_NAME = "$(TARGET_NAME)";
  449 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  450 + SWIFT_VERSION = 5.0;
  451 + VERSIONING_SYSTEM = "apple-generic";
  452 + };
  453 + name = Release;
  454 + };
  455 +/* End XCBuildConfiguration section */
  456 +
  457 +/* Begin XCConfigurationList section */
  458 + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
  459 + isa = XCConfigurationList;
  460 + buildConfigurations = (
  461 + 97C147031CF9000F007C117D /* Debug */,
  462 + 97C147041CF9000F007C117D /* Release */,
  463 + 249021D3217E4FDB00AE95B9 /* Profile */,
  464 + );
  465 + defaultConfigurationIsVisible = 0;
  466 + defaultConfigurationName = Release;
  467 + };
  468 + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
  469 + isa = XCConfigurationList;
  470 + buildConfigurations = (
  471 + 97C147061CF9000F007C117D /* Debug */,
  472 + 97C147071CF9000F007C117D /* Release */,
  473 + 249021D4217E4FDB00AE95B9 /* Profile */,
  474 + );
  475 + defaultConfigurationIsVisible = 0;
  476 + defaultConfigurationName = Release;
  477 + };
  478 +/* End XCConfigurationList section */
  479 + };
  480 + rootObject = 97C146E61CF9000F007C117D /* Project object */;
  481 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "self:">
  6 + </FileRef>
  7 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>PreviewsEnabled</key>
  6 + <false/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Scheme
  3 + LastUpgradeVersion = "1300"
  4 + version = "1.3">
  5 + <BuildAction
  6 + parallelizeBuildables = "YES"
  7 + buildImplicitDependencies = "YES">
  8 + <BuildActionEntries>
  9 + <BuildActionEntry
  10 + buildForTesting = "YES"
  11 + buildForRunning = "YES"
  12 + buildForProfiling = "YES"
  13 + buildForArchiving = "YES"
  14 + buildForAnalyzing = "YES">
  15 + <BuildableReference
  16 + BuildableIdentifier = "primary"
  17 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  18 + BuildableName = "Runner.app"
  19 + BlueprintName = "Runner"
  20 + ReferencedContainer = "container:Runner.xcodeproj">
  21 + </BuildableReference>
  22 + </BuildActionEntry>
  23 + </BuildActionEntries>
  24 + </BuildAction>
  25 + <TestAction
  26 + buildConfiguration = "Debug"
  27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  29 + shouldUseLaunchSchemeArgsEnv = "YES">
  30 + <MacroExpansion>
  31 + <BuildableReference
  32 + BuildableIdentifier = "primary"
  33 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  34 + BuildableName = "Runner.app"
  35 + BlueprintName = "Runner"
  36 + ReferencedContainer = "container:Runner.xcodeproj">
  37 + </BuildableReference>
  38 + </MacroExpansion>
  39 + <Testables>
  40 + </Testables>
  41 + </TestAction>
  42 + <LaunchAction
  43 + buildConfiguration = "Debug"
  44 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  45 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  46 + launchStyle = "0"
  47 + useCustomWorkingDirectory = "NO"
  48 + ignoresPersistentStateOnLaunch = "NO"
  49 + debugDocumentVersioning = "YES"
  50 + debugServiceExtension = "internal"
  51 + allowLocationSimulation = "YES">
  52 + <BuildableProductRunnable
  53 + runnableDebuggingMode = "0">
  54 + <BuildableReference
  55 + BuildableIdentifier = "primary"
  56 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  57 + BuildableName = "Runner.app"
  58 + BlueprintName = "Runner"
  59 + ReferencedContainer = "container:Runner.xcodeproj">
  60 + </BuildableReference>
  61 + </BuildableProductRunnable>
  62 + </LaunchAction>
  63 + <ProfileAction
  64 + buildConfiguration = "Profile"
  65 + shouldUseLaunchSchemeArgsEnv = "YES"
  66 + savedToolIdentifier = ""
  67 + useCustomWorkingDirectory = "NO"
  68 + debugDocumentVersioning = "YES">
  69 + <BuildableProductRunnable
  70 + runnableDebuggingMode = "0">
  71 + <BuildableReference
  72 + BuildableIdentifier = "primary"
  73 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  74 + BuildableName = "Runner.app"
  75 + BlueprintName = "Runner"
  76 + ReferencedContainer = "container:Runner.xcodeproj">
  77 + </BuildableReference>
  78 + </BuildableProductRunnable>
  79 + </ProfileAction>
  80 + <AnalyzeAction
  81 + buildConfiguration = "Debug">
  82 + </AnalyzeAction>
  83 + <ArchiveAction
  84 + buildConfiguration = "Release"
  85 + revealArchiveInOrganizer = "YES">
  86 + </ArchiveAction>
  87 +</Scheme>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "group:Runner.xcodeproj">
  6 + </FileRef>
  7 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>PreviewsEnabled</key>
  6 + <false/>
  7 +</dict>
  8 +</plist>
  1 +import UIKit
  2 +import Flutter
  3 +
  4 +@UIApplicationMain
  5 +@objc class AppDelegate: FlutterAppDelegate {
  6 + override func application(
  7 + _ application: UIApplication,
  8 + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  9 + ) -> Bool {
  10 + GeneratedPluginRegistrant.register(with: self)
  11 + return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  12 + }
  13 +}
  1 +{
  2 + "images" : [
  3 + {
  4 + "size" : "20x20",
  5 + "idiom" : "iphone",
  6 + "filename" : "Icon-App-20x20@2x.png",
  7 + "scale" : "2x"
  8 + },
  9 + {
  10 + "size" : "20x20",
  11 + "idiom" : "iphone",
  12 + "filename" : "Icon-App-20x20@3x.png",
  13 + "scale" : "3x"
  14 + },
  15 + {
  16 + "size" : "29x29",
  17 + "idiom" : "iphone",
  18 + "filename" : "Icon-App-29x29@1x.png",
  19 + "scale" : "1x"
  20 + },
  21 + {
  22 + "size" : "29x29",
  23 + "idiom" : "iphone",
  24 + "filename" : "Icon-App-29x29@2x.png",
  25 + "scale" : "2x"
  26 + },
  27 + {
  28 + "size" : "29x29",
  29 + "idiom" : "iphone",
  30 + "filename" : "Icon-App-29x29@3x.png",
  31 + "scale" : "3x"
  32 + },
  33 + {
  34 + "size" : "40x40",
  35 + "idiom" : "iphone",
  36 + "filename" : "Icon-App-40x40@2x.png",
  37 + "scale" : "2x"
  38 + },
  39 + {
  40 + "size" : "40x40",
  41 + "idiom" : "iphone",
  42 + "filename" : "Icon-App-40x40@3x.png",
  43 + "scale" : "3x"
  44 + },
  45 + {
  46 + "size" : "60x60",
  47 + "idiom" : "iphone",
  48 + "filename" : "Icon-App-60x60@2x.png",
  49 + "scale" : "2x"
  50 + },
  51 + {
  52 + "size" : "60x60",
  53 + "idiom" : "iphone",
  54 + "filename" : "Icon-App-60x60@3x.png",
  55 + "scale" : "3x"
  56 + },
  57 + {
  58 + "size" : "20x20",
  59 + "idiom" : "ipad",
  60 + "filename" : "Icon-App-20x20@1x.png",
  61 + "scale" : "1x"
  62 + },
  63 + {
  64 + "size" : "20x20",
  65 + "idiom" : "ipad",
  66 + "filename" : "Icon-App-20x20@2x.png",
  67 + "scale" : "2x"
  68 + },
  69 + {
  70 + "size" : "29x29",
  71 + "idiom" : "ipad",
  72 + "filename" : "Icon-App-29x29@1x.png",
  73 + "scale" : "1x"
  74 + },
  75 + {
  76 + "size" : "29x29",
  77 + "idiom" : "ipad",
  78 + "filename" : "Icon-App-29x29@2x.png",
  79 + "scale" : "2x"
  80 + },
  81 + {
  82 + "size" : "40x40",
  83 + "idiom" : "ipad",
  84 + "filename" : "Icon-App-40x40@1x.png",
  85 + "scale" : "1x"
  86 + },
  87 + {
  88 + "size" : "40x40",
  89 + "idiom" : "ipad",
  90 + "filename" : "Icon-App-40x40@2x.png",
  91 + "scale" : "2x"
  92 + },
  93 + {
  94 + "size" : "76x76",
  95 + "idiom" : "ipad",
  96 + "filename" : "Icon-App-76x76@1x.png",
  97 + "scale" : "1x"
  98 + },
  99 + {
  100 + "size" : "76x76",
  101 + "idiom" : "ipad",
  102 + "filename" : "Icon-App-76x76@2x.png",
  103 + "scale" : "2x"
  104 + },
  105 + {
  106 + "size" : "83.5x83.5",
  107 + "idiom" : "ipad",
  108 + "filename" : "Icon-App-83.5x83.5@2x.png",
  109 + "scale" : "2x"
  110 + },
  111 + {
  112 + "size" : "1024x1024",
  113 + "idiom" : "ios-marketing",
  114 + "filename" : "Icon-App-1024x1024@1x.png",
  115 + "scale" : "1x"
  116 + }
  117 + ],
  118 + "info" : {
  119 + "version" : 1,
  120 + "author" : "xcode"
  121 + }
  122 +}
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "universal",
  5 + "filename" : "LaunchImage.png",
  6 + "scale" : "1x"
  7 + },
  8 + {
  9 + "idiom" : "universal",
  10 + "filename" : "LaunchImage@2x.png",
  11 + "scale" : "2x"
  12 + },
  13 + {
  14 + "idiom" : "universal",
  15 + "filename" : "LaunchImage@3x.png",
  16 + "scale" : "3x"
  17 + }
  18 + ],
  19 + "info" : {
  20 + "version" : 1,
  21 + "author" : "xcode"
  22 + }
  23 +}
  1 +# Launch Screen Assets
  2 +
  3 +You can customize the launch screen with your own desired assets by replacing the image files in this directory.
  4 +
  5 +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
  6 + </dependencies>
  7 + <scenes>
  8 + <!--View Controller-->
  9 + <scene sceneID="EHf-IW-A2E">
  10 + <objects>
  11 + <viewController id="01J-lp-oVM" sceneMemberID="viewController">
  12 + <layoutGuides>
  13 + <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
  14 + <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
  15 + </layoutGuides>
  16 + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
  17 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  18 + <subviews>
  19 + <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
  20 + </imageView>
  21 + </subviews>
  22 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  23 + <constraints>
  24 + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
  25 + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
  26 + </constraints>
  27 + </view>
  28 + </viewController>
  29 + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
  30 + </objects>
  31 + <point key="canvasLocation" x="53" y="375"/>
  32 + </scene>
  33 + </scenes>
  34 + <resources>
  35 + <image name="LaunchImage" width="168" height="185"/>
  36 + </resources>
  37 +</document>
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
  6 + </dependencies>
  7 + <scenes>
  8 + <!--Flutter View Controller-->
  9 + <scene sceneID="tne-QT-ifu">
  10 + <objects>
  11 + <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
  12 + <layoutGuides>
  13 + <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
  14 + <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
  15 + </layoutGuides>
  16 + <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
  17 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  18 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  19 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  20 + </view>
  21 + </viewController>
  22 + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
  23 + </objects>
  24 + </scene>
  25 + </scenes>
  26 +</document>
  1 +//
  2 +// Generated file. Do not edit.
  3 +//
  4 +
  5 +// clang-format off
  6 +
  7 +#ifndef GeneratedPluginRegistrant_h
  8 +#define GeneratedPluginRegistrant_h
  9 +
  10 +#import <Flutter/Flutter.h>
  11 +
  12 +NS_ASSUME_NONNULL_BEGIN
  13 +
  14 +@interface GeneratedPluginRegistrant : NSObject
  15 ++ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
  16 +@end
  17 +
  18 +NS_ASSUME_NONNULL_END
  19 +#endif /* GeneratedPluginRegistrant_h */
  1 +//
  2 +// Generated file. Do not edit.
  3 +//
  4 +
  5 +// clang-format off
  6 +
  7 +#import "GeneratedPluginRegistrant.h"
  8 +
  9 +@implementation GeneratedPluginRegistrant
  10 +
  11 ++ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
  12 +}
  13 +
  14 +@end
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>$(DEVELOPMENT_LANGUAGE)</string>
  7 + <key>CFBundleDisplayName</key>
  8 + <string>Example</string>
  9 + <key>CFBundleExecutable</key>
  10 + <string>$(EXECUTABLE_NAME)</string>
  11 + <key>CFBundleIdentifier</key>
  12 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  13 + <key>CFBundleInfoDictionaryVersion</key>
  14 + <string>6.0</string>
  15 + <key>CFBundleName</key>
  16 + <string>example</string>
  17 + <key>CFBundlePackageType</key>
  18 + <string>APPL</string>
  19 + <key>CFBundleShortVersionString</key>
  20 + <string>$(FLUTTER_BUILD_NAME)</string>
  21 + <key>CFBundleSignature</key>
  22 + <string>????</string>
  23 + <key>CFBundleVersion</key>
  24 + <string>$(FLUTTER_BUILD_NUMBER)</string>
  25 + <key>LSRequiresIPhoneOS</key>
  26 + <true/>
  27 + <key>UILaunchStoryboardName</key>
  28 + <string>LaunchScreen</string>
  29 + <key>UIMainStoryboardFile</key>
  30 + <string>Main</string>
  31 + <key>UISupportedInterfaceOrientations</key>
  32 + <array>
  33 + <string>UIInterfaceOrientationPortrait</string>
  34 + <string>UIInterfaceOrientationLandscapeLeft</string>
  35 + <string>UIInterfaceOrientationLandscapeRight</string>
  36 + </array>
  37 + <key>UISupportedInterfaceOrientations~ipad</key>
  38 + <array>
  39 + <string>UIInterfaceOrientationPortrait</string>
  40 + <string>UIInterfaceOrientationPortraitUpsideDown</string>
  41 + <string>UIInterfaceOrientationLandscapeLeft</string>
  42 + <string>UIInterfaceOrientationLandscapeRight</string>
  43 + </array>
  44 + <key>UIViewControllerBasedStatusBarAppearance</key>
  45 + <false/>
  46 + <key>CADisableMinimumFrameDurationOnPhone</key>
  47 + <true/>
  48 + <key>UIApplicationSupportsIndirectInputEvents</key>
  49 + <true/>
  50 +</dict>
  51 +</plist>
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_lunar_datetime_picker/date_init.dart';
  3 +import 'package:flutter_lunar_datetime_picker/flutter_lunar_datetime_picker.dart';
  4 +import 'package:intl/intl.dart';
  5 +
  6 +void main() {
  7 + runApp(const MyApp());
  8 +}
  9 +
  10 +class MyApp extends StatelessWidget {
  11 + const MyApp({super.key});
  12 +
  13 + // This widget is the root of your application.
  14 + @override
  15 + Widget build(BuildContext context) {
  16 + return MaterialApp(
  17 + title: 'Flutter Demo',
  18 + theme: ThemeData(
  19 + primarySwatch: Colors.blue,
  20 + ),
  21 + home: const HomePage(),
  22 + );
  23 + }
  24 +}
  25 +
  26 +class HomePage extends StatefulWidget {
  27 + const HomePage({super.key});
  28 +
  29 + @override
  30 + State<HomePage> createState() => _HomePageState();
  31 +}
  32 +
  33 +class _HomePageState extends State<HomePage> {
  34 + /// 日期
  35 + String? time = '1995-11-8 12:12';
  36 +
  37 + /// 是否是农历
  38 + bool lunar = true;
  39 +
  40 + @override
  41 + Widget build(BuildContext context) {
  42 + return Scaffold(
  43 + appBar: AppBar(
  44 + title: const Text("日期选择器"),
  45 + ),
  46 + body: Center(
  47 + child: Column(
  48 + mainAxisSize: MainAxisSize.min,
  49 + children: [
  50 + Text(
  51 + "日期:$time",
  52 + style: const TextStyle(fontSize: 30),
  53 + ),
  54 + const SizedBox(height: 100),
  55 + ElevatedButton(
  56 + onPressed: () {
  57 + DatePicker.showDatePicker(
  58 + context,
  59 + lunarPicker: lunar,
  60 + showTime: true,
  61 + showLunarYear: true,
  62 + dateInitTime: time == null
  63 + ? DateInitTime(
  64 + currentTime: DateTime.now(),
  65 + maxTime: DateTime(2026, 12, 12),
  66 + minTime: DateTime(1995, 2, 4))
  67 + : DateInitTime(
  68 + currentTime:
  69 + DateFormat("yyyy-MM-dd h:m").parse(time ?? ""),
  70 + maxTime: DateTime(2026, 12, 12),
  71 + minTime: DateTime(1995, 2, 4)),
  72 + onConfirm: (time, lunar) {
  73 + debugPrint(time.toString());
  74 + setState(() {
  75 + this.time =
  76 + "${time.year}-${time.month}-${time.day} ${time.hour}:${time.minute}";
  77 + this.lunar = lunar;
  78 + });
  79 + },
  80 + onChanged: (time, lunar) {
  81 + debugPrint("change:${time.toString()}");
  82 + },
  83 + );
  84 + },
  85 + child: const Text("选择"),
  86 + )
  87 + ],
  88 + )),
  89 + );
  90 + }
  91 +}
  1 +# Generated by pub
  2 +# See https://dart.dev/tools/pub/glossary#lockfile
  3 +packages:
  4 + async:
  5 + dependency: transitive
  6 + description:
  7 + name: async
  8 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
  9 + url: "https://pub.flutter-io.cn"
  10 + source: hosted
  11 + version: "2.11.0"
  12 + boolean_selector:
  13 + dependency: transitive
  14 + description:
  15 + name: boolean_selector
  16 + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
  17 + url: "https://pub.flutter-io.cn"
  18 + source: hosted
  19 + version: "2.1.1"
  20 + characters:
  21 + dependency: transitive
  22 + description:
  23 + name: characters
  24 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
  25 + url: "https://pub.flutter-io.cn"
  26 + source: hosted
  27 + version: "1.3.0"
  28 + clock:
  29 + dependency: transitive
  30 + description:
  31 + name: clock
  32 + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
  33 + url: "https://pub.flutter-io.cn"
  34 + source: hosted
  35 + version: "1.1.1"
  36 + collection:
  37 + dependency: transitive
  38 + description:
  39 + name: collection
  40 + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
  41 + url: "https://pub.flutter-io.cn"
  42 + source: hosted
  43 + version: "1.19.0"
  44 + cupertino_icons:
  45 + dependency: "direct main"
  46 + description:
  47 + name: cupertino_icons
  48 + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
  49 + url: "https://pub.flutter-io.cn"
  50 + source: hosted
  51 + version: "1.0.8"
  52 + fake_async:
  53 + dependency: transitive
  54 + description:
  55 + name: fake_async
  56 + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
  57 + url: "https://pub.flutter-io.cn"
  58 + source: hosted
  59 + version: "1.3.1"
  60 + flutter:
  61 + dependency: "direct main"
  62 + description: flutter
  63 + source: sdk
  64 + version: "0.0.0"
  65 + flutter_lints:
  66 + dependency: "direct dev"
  67 + description:
  68 + name: flutter_lints
  69 + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
  70 + url: "https://pub.flutter-io.cn"
  71 + source: hosted
  72 + version: "2.0.3"
  73 + flutter_lunar_datetime_picker:
  74 + dependency: "direct main"
  75 + description:
  76 + path: ".."
  77 + relative: true
  78 + source: path
  79 + version: "1.0.6"
  80 + flutter_test:
  81 + dependency: "direct dev"
  82 + description: flutter
  83 + source: sdk
  84 + version: "0.0.0"
  85 + intl:
  86 + dependency: "direct main"
  87 + description:
  88 + name: intl
  89 + sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
  90 + url: "https://pub.flutter-io.cn"
  91 + source: hosted
  92 + version: "0.17.0"
  93 + leak_tracker:
  94 + dependency: transitive
  95 + description:
  96 + name: leak_tracker
  97 + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
  98 + url: "https://pub.flutter-io.cn"
  99 + source: hosted
  100 + version: "10.0.7"
  101 + leak_tracker_flutter_testing:
  102 + dependency: transitive
  103 + description:
  104 + name: leak_tracker_flutter_testing
  105 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
  106 + url: "https://pub.flutter-io.cn"
  107 + source: hosted
  108 + version: "3.0.8"
  109 + leak_tracker_testing:
  110 + dependency: transitive
  111 + description:
  112 + name: leak_tracker_testing
  113 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
  114 + url: "https://pub.flutter-io.cn"
  115 + source: hosted
  116 + version: "3.0.1"
  117 + lints:
  118 + dependency: transitive
  119 + description:
  120 + name: lints
  121 + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
  122 + url: "https://pub.flutter-io.cn"
  123 + source: hosted
  124 + version: "2.1.1"
  125 + lunar:
  126 + dependency: "direct main"
  127 + description:
  128 + name: lunar
  129 + sha256: "4ebb40c1647c5903fc67ff0be09a4ce90da79b482f0c78a8c727086a67375c37"
  130 + url: "https://pub.flutter-io.cn"
  131 + source: hosted
  132 + version: "1.7.5"
  133 + matcher:
  134 + dependency: transitive
  135 + description:
  136 + name: matcher
  137 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
  138 + url: "https://pub.flutter-io.cn"
  139 + source: hosted
  140 + version: "0.12.16+1"
  141 + material_color_utilities:
  142 + dependency: transitive
  143 + description:
  144 + name: material_color_utilities
  145 + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
  146 + url: "https://pub.flutter-io.cn"
  147 + source: hosted
  148 + version: "0.11.1"
  149 + meta:
  150 + dependency: transitive
  151 + description:
  152 + name: meta
  153 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
  154 + url: "https://pub.flutter-io.cn"
  155 + source: hosted
  156 + version: "1.15.0"
  157 + path:
  158 + dependency: transitive
  159 + description:
  160 + name: path
  161 + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
  162 + url: "https://pub.flutter-io.cn"
  163 + source: hosted
  164 + version: "1.9.0"
  165 + sky_engine:
  166 + dependency: transitive
  167 + description: flutter
  168 + source: sdk
  169 + version: "0.0.0"
  170 + source_span:
  171 + dependency: transitive
  172 + description:
  173 + name: source_span
  174 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
  175 + url: "https://pub.flutter-io.cn"
  176 + source: hosted
  177 + version: "1.10.0"
  178 + stack_trace:
  179 + dependency: transitive
  180 + description:
  181 + name: stack_trace
  182 + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
  183 + url: "https://pub.flutter-io.cn"
  184 + source: hosted
  185 + version: "1.12.0"
  186 + stream_channel:
  187 + dependency: transitive
  188 + description:
  189 + name: stream_channel
  190 + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
  191 + url: "https://pub.flutter-io.cn"
  192 + source: hosted
  193 + version: "2.1.2"
  194 + string_scanner:
  195 + dependency: transitive
  196 + description:
  197 + name: string_scanner
  198 + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
  199 + url: "https://pub.flutter-io.cn"
  200 + source: hosted
  201 + version: "1.3.0"
  202 + term_glyph:
  203 + dependency: transitive
  204 + description:
  205 + name: term_glyph
  206 + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
  207 + url: "https://pub.flutter-io.cn"
  208 + source: hosted
  209 + version: "1.2.1"
  210 + test_api:
  211 + dependency: transitive
  212 + description:
  213 + name: test_api
  214 + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
  215 + url: "https://pub.flutter-io.cn"
  216 + source: hosted
  217 + version: "0.7.3"
  218 + vector_math:
  219 + dependency: transitive
  220 + description:
  221 + name: vector_math
  222 + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
  223 + url: "https://pub.flutter-io.cn"
  224 + source: hosted
  225 + version: "2.1.4"
  226 + vm_service:
  227 + dependency: transitive
  228 + description:
  229 + name: vm_service
  230 + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
  231 + url: "https://pub.flutter-io.cn"
  232 + source: hosted
  233 + version: "14.3.0"
  234 +sdks:
  235 + dart: ">=3.4.0 <4.0.0"
  236 + flutter: ">=3.18.0-18.0.pre.54"
  1 +name: example
  2 +description: A new Flutter project.
  3 +
  4 +# The following line prevents the package from being accidentally published to
  5 +# pub.dev using `flutter pub publish`. This is preferred for private packages.
  6 +publish_to: 'none' # Remove this line if you wish to publish to pub.dev
  7 +
  8 +# The following defines the version and build number for your application.
  9 +# A version number is three numbers separated by dots, like 1.2.43
  10 +# followed by an optional build number separated by a +.
  11 +# Both the version and the builder number may be overridden in flutter
  12 +# build by specifying --build-name and --build-number, respectively.
  13 +# In Android, build-name is used as versionName while build-number used as versionCode.
  14 +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
  15 +# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
  16 +# Read more about iOS versioning at
  17 +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
  18 +# In Windows, build-name is used as the major, minor, and patch parts
  19 +# of the product and file versions while build-number is used as the build suffix.
  20 +version: 1.0.0+1
  21 +
  22 +environment:
  23 + sdk: '>=2.18.1 <3.0.0'
  24 +
  25 +# Dependencies specify other packages that your package needs in order to work.
  26 +# To automatically upgrade your package dependencies to the latest versions
  27 +# consider running `flutter pub upgrade --major-versions`. Alternatively,
  28 +# dependencies can be manually updated by changing the version numbers below to
  29 +# the latest version available on pub.dev. To see which dependencies have newer
  30 +# versions available, run `flutter pub outdated`.
  31 +dependencies:
  32 + flutter:
  33 + sdk: flutter
  34 +
  35 +
  36 + # The following adds the Cupertino Icons font to your application.
  37 + # Use with the CupertinoIcons class for iOS style icons.
  38 + cupertino_icons: ^1.0.2
  39 +
  40 + flutter_lunar_datetime_picker:
  41 + path: ../
  42 + lunar: ^1.2.21
  43 + intl: ^0.17.0
  44 +
  45 +dev_dependencies:
  46 + flutter_test:
  47 + sdk: flutter
  48 +
  49 + # The "flutter_lints" package below contains a set of recommended lints to
  50 + # encourage good coding practices. The lint set provided by the package is
  51 + # activated in the `analysis_options.yaml` file located at the root of your
  52 + # package. See that file for information about deactivating specific lint
  53 + # rules and activating additional ones.
  54 + flutter_lints: ^2.0.0
  55 +
  56 +# For information on the generic Dart part of this file, see the
  57 +# following page: https://dart.dev/tools/pub/pubspec
  58 +
  59 +# The following section is specific to Flutter packages.
  60 +flutter:
  61 +
  62 + # The following line ensures that the Material Icons font is
  63 + # included with your application, so that you can use the icons in
  64 + # the material Icons class.
  65 + uses-material-design: true
  66 +
  67 + # To add assets to your application, add an assets section, like this:
  68 + # assets:
  69 + # - images/a_dot_burr.jpeg
  70 + # - images/a_dot_ham.jpeg
  71 +
  72 + # An image asset can refer to one or more resolution-specific "variants", see
  73 + # https://flutter.dev/assets-and-images/#resolution-aware
  74 +
  75 + # For details regarding adding assets from package dependencies, see
  76 + # https://flutter.dev/assets-and-images/#from-packages
  77 +
  78 + # To add custom fonts to your application, add a fonts section here,
  79 + # in this "flutter" section. Each entry in this list should have a
  80 + # "family" key with the font family name, and a "fonts" key with a
  81 + # list giving the asset and other descriptors for the font. For
  82 + # example:
  83 + # fonts:
  84 + # - family: Schyler
  85 + # fonts:
  86 + # - asset: fonts/Schyler-Regular.ttf
  87 + # - asset: fonts/Schyler-Italic.ttf
  88 + # style: italic
  89 + # - family: Trajan Pro
  90 + # fonts:
  91 + # - asset: fonts/TrajanPro.ttf
  92 + # - asset: fonts/TrajanPro_Bold.ttf
  93 + # weight: 700
  94 + #
  95 + # For details regarding fonts from package dependencies,
  96 + # see https://flutter.dev/custom-fonts/#from-packages
  1 +// This is a basic Flutter widget test.
  2 +//
  3 +// To perform an interaction with a widget in your test, use the WidgetTester
  4 +// utility in the flutter_test package. For example, you can send tap and scroll
  5 +// gestures. You can also use WidgetTester to find child widgets in the widget
  6 +// tree, read text, and verify that the values of widget properties are correct.
  7 +
  8 +import 'package:flutter/material.dart';
  9 +import 'package:flutter_test/flutter_test.dart';
  10 +
  11 +import 'package:example/main.dart';
  12 +
  13 +void main() {
  14 + testWidgets('Counter increments smoke test', (WidgetTester tester) async {
  15 + // Build our app and trigger a frame.
  16 + await tester.pumpWidget(const MyApp());
  17 +
  18 + // Verify that our counter starts at 0.
  19 + expect(find.text('0'), findsOneWidget);
  20 + expect(find.text('1'), findsNothing);
  21 +
  22 + // Tap the '+' icon and trigger a frame.
  23 + await tester.tap(find.byIcon(Icons.add));
  24 + await tester.pump();
  25 +
  26 + // Verify that our counter has incremented.
  27 + expect(find.text('0'), findsNothing);
  28 + expect(find.text('1'), findsOneWidget);
  29 + });
  30 +}
  1 +
  2 +/// Outputs year as four digits
  3 +///
  4 +/// Example:
  5 +/// formatDate(new DateTime(2018,8,31), [yMDW]);
  6 +/// // => Today
  7 +const String yMDW = 'ymdw';
  8 +
  9 +///
  10 +/// Example:
  11 +/// formatDate(new DateTime(1989), [yyyy]);
  12 +/// // => 1989
  13 +const String yyyy = 'yyyy';
  14 +
  15 +/// Outputs year as two digits
  16 +///
  17 +/// Example:
  18 +/// formatDate(new DateTime(1989), [yy]);
  19 +/// // => 89
  20 +const String yy = 'yy';
  21 +
  22 +/// Outputs month as two digits
  23 +///
  24 +/// Example:
  25 +/// formatDate(new DateTime(1989, 11), [mm]);
  26 +/// // => 11
  27 +/// formatDate(new DateTime(1989, 5), [mm]);
  28 +/// // => 05
  29 +const String mm = 'mm';
  30 +
  31 +/// Outputs month compactly
  32 +///
  33 +/// Example:
  34 +/// formatDate(new DateTime(1989, 11), [mm]);
  35 +/// // => 11
  36 +/// formatDate(new DateTime(1989, 5), [m]);
  37 +/// // => 5
  38 +const String m = 'm';
  39 +
  40 +/// Outputs month as long name
  41 +///
  42 +/// Example:
  43 +/// formatDate(new DateTime(1989, 2), [mM]);
  44 +/// // => february
  45 +const String mM = 'MM';
  46 +
  47 +/// Outputs month as short name
  48 +///
  49 +/// Example:
  50 +/// formatDate(new DateTime(1989, 2), [M]);
  51 +/// // => feb
  52 +const String M = 'M';
  53 +
  54 +/// Outputs day as two digits
  55 +///
  56 +/// Example:
  57 +/// formatDate(new DateTime(1989, 2, 21), [dd]);
  58 +/// // => 21
  59 +/// formatDate(new DateTime(1989, 2, 5), [dd]);
  60 +/// // => 05
  61 +const String dd = 'dd';
  62 +
  63 +/// Outputs day compactly
  64 +///
  65 +/// Example:
  66 +/// formatDate(new DateTime(1989, 2, 21), [d]);
  67 +/// // => 21
  68 +/// formatDate(new DateTime(1989, 2, 5), [d]);
  69 +/// // => 5
  70 +const String d = 'd';
  71 +
  72 +/// Outputs week in month
  73 +///
  74 +/// Example:
  75 +/// formatDate(new DateTime(1989, 2, 21), [w]);
  76 +/// // => 4
  77 +const String w = 'w';
  78 +
  79 +/// Outputs week in year as two digits
  80 +///
  81 +/// Example:
  82 +/// formatDate(new DateTime(1989, 12, 31), [W]);
  83 +/// // => 53
  84 +/// formatDate(new DateTime(1989, 2, 21), [W]);
  85 +/// // => 08
  86 +const String wW = 'WW';
  87 +
  88 +/// Outputs week in year compactly
  89 +///
  90 +/// Example:
  91 +/// formatDate(new DateTime(1989, 2, 21), [W]);
  92 +/// // => 8
  93 +const String W = 'W';
  94 +
  95 +/// Outputs week day as long name
  96 +///
  97 +/// Example:
  98 +/// formatDate(new DateTime(2018, 1, 14), [D]);
  99 +/// // => sun
  100 +const String D = 'D';
  101 +
  102 +/// Outputs hour (0 - 11) as two digits
  103 +///
  104 +/// Example:
  105 +/// formatDate(new DateTime(1989, 02, 1, 15), [hh]);
  106 +/// // => 03
  107 +const String hh = 'hh';
  108 +
  109 +/// Outputs hour (0 - 11) compactly
  110 +///
  111 +/// Example:
  112 +/// formatDate(new DateTime(1989, 02, 1, 15), [h]);
  113 +/// // => 3
  114 +const String h = 'h';
  115 +
  116 +/// Outputs hour (0 to 23) as two digits
  117 +///
  118 +/// Example:
  119 +/// formatDate(new DateTime(1989, 02, 1, 15), [hH]);
  120 +/// // => 15
  121 +const String hH = 'HH';
  122 +
  123 +/// Outputs hour (0 to 23) compactly
  124 +///
  125 +/// Example:
  126 +/// formatDate(new DateTime(1989, 02, 1, 5), [H]);
  127 +/// // => 5
  128 +const String H = 'H';
  129 +
  130 +/// Outputs minute as two digits
  131 +///
  132 +/// Example:
  133 +/// formatDate(new DateTime(1989, 02, 1, 15, 40), [nn]);
  134 +/// // => 40
  135 +/// formatDate(new DateTime(1989, 02, 1, 15, 4), [nn]);
  136 +/// // => 04
  137 +const String nn = 'nn';
  138 +
  139 +/// Outputs minute compactly
  140 +///
  141 +/// Example:
  142 +/// formatDate(new DateTime(1989, 02, 1, 15, 4), [n]);
  143 +/// // => 4
  144 +const String n = 'n';
  145 +
  146 +/// Outputs second as two digits
  147 +///
  148 +/// Example:
  149 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10), [ss]);
  150 +/// // => 10
  151 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 5), [ss]);
  152 +/// // => 05
  153 +const String ss = 'ss';
  154 +
  155 +/// Outputs second compactly
  156 +///
  157 +/// Example:
  158 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 5), [s]);
  159 +/// // => 5
  160 +const String s = 's';
  161 +
  162 +/// Outputs millisecond as three digits
  163 +///
  164 +/// Example:
  165 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 999), [sSS]);
  166 +/// // => 999
  167 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 99), [SS]);
  168 +/// // => 099
  169 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0), [SS]);
  170 +/// // => 009
  171 +const String sSS = 'SSS';
  172 +
  173 +/// Outputs millisecond compactly
  174 +///
  175 +/// Example:
  176 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 999), [sSS]);
  177 +/// // => 999
  178 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 99), [SS]);
  179 +/// // => 99
  180 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 9), [SS]);
  181 +/// // => 9
  182 +const String S = 'S';
  183 +
  184 +/// Outputs microsecond as three digits
  185 +///
  186 +/// Example:
  187 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 999), [uuu]);
  188 +/// // => 999
  189 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 99), [uuu]);
  190 +/// // => 099
  191 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 9), [uuu]);
  192 +/// // => 009
  193 +const String uuu = 'uuu';
  194 +
  195 +/// Outputs millisecond compactly
  196 +///
  197 +/// Example:
  198 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 999), [u]);
  199 +/// // => 999
  200 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 99), [u]);
  201 +/// // => 99
  202 +/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 9), [u]);
  203 +/// // => 9
  204 +const String u = 'u';
  205 +
  206 +/// Outputs if hour is AM or PM
  207 +///
  208 +/// Example:
  209 +/// print(formatDate(new DateTime(1989, 02, 1, 5), [am]));
  210 +/// // => AM
  211 +/// print(formatDate(new DateTime(1989, 02, 1, 15), [am]));
  212 +/// // => PM
  213 +const String am = 'am';
  214 +
  215 +/// Outputs timezone as time offset
  216 +///
  217 +/// Example:
  218 +///
  219 +const String z = 'z';
  220 +const String Z = 'Z';
  221 +
  222 +
  223 +String digits(int value, int length) {
  224 + return '$value'.padLeft(length, "0");
  225 +}
  226 +
  227 +int dayInYear(DateTime date) =>
  228 + date.difference(DateTime(date.year, 1, 1)).inDays;
  1 +class DateInitTime {
  2 + DateInitTime({
  3 + this.currentTime,
  4 + this.maxTime,
  5 + this.minTime,
  6 + });
  7 + DateTime? currentTime;
  8 + DateTime? maxTime;
  9 + DateTime? minTime;
  10 +}
  1 +import 'package:flutter/cupertino.dart';
  2 +import 'package:flutter_lunar_datetime_picker/date_format.dart';
  3 +import 'package:flutter_lunar_datetime_picker/datetime_util.dart';
  4 +import 'package:lunar/lunar.dart';
  5 +
  6 +//interface for picker data model
  7 +abstract class BasePickerModel {
  8 + //a getter method for left column data, return null to end list
  9 + String? leftStringAtIndex(int index);
  10 +
  11 + //a getter method for middle column data, return null to end list
  12 + String? middleStringAtIndex(int index);
  13 +
  14 + //a getter method for right column data, return null to end list
  15 + String? rightStringAtIndex(int index);
  16 +
  17 + String? hourStringAtIndex(int index);
  18 +
  19 + String? minuteStringAtIndex(int index);
  20 +
  21 + //set selected left index
  22 + void setLeftIndex(int index);
  23 +
  24 + //set selected middle index
  25 + void setMiddleIndex(int index);
  26 +
  27 + //set selected right index
  28 + void setRightIndex(int index);
  29 +
  30 + void setHourIndex(int index);
  31 +
  32 + void setMinuteIndex(int index);
  33 +
  34 + //return current left index
  35 + int currentLeftIndex();
  36 +
  37 + //return current middle index
  38 + int currentMiddleIndex();
  39 +
  40 + //return current right index
  41 + int currentRightIndex();
  42 +
  43 + int currentHourIndex();
  44 +
  45 + int currentMinuteIndex();
  46 +
  47 + //return final time
  48 + DateTime? finalTime();
  49 +
  50 + //return left divider string
  51 + String leftDivider();
  52 +
  53 + //return right divider string
  54 + String rightDivider();
  55 +
  56 + String timeDivider();
  57 +
  58 + //layout proportions for 3 columns
  59 + List<int> layoutProportions();
  60 +}
  61 +
  62 +//a base class for picker data model
  63 +class CommonPickerModel extends BasePickerModel {
  64 + late List<String> leftList;
  65 + late List<String> middleList;
  66 + late List<String> rightList;
  67 + late List<String> hourList;
  68 + late List<String> minuteList;
  69 + late DateTime currentTime;
  70 + late int _currentLeftIndex;
  71 + late int _currentMiddleIndex;
  72 + late int _currentRightIndex;
  73 + late int _currentHourIndex;
  74 + late int _currentMinuteIndex;
  75 +
  76 + CommonPickerModel();
  77 +
  78 + @override
  79 + String? leftStringAtIndex(int index) {
  80 + return null;
  81 + }
  82 +
  83 + @override
  84 + String? middleStringAtIndex(int index) {
  85 + return null;
  86 + }
  87 +
  88 + @override
  89 + String? rightStringAtIndex(int index) {
  90 + return null;
  91 + }
  92 +
  93 + @override
  94 + int currentLeftIndex() {
  95 + return _currentLeftIndex;
  96 + }
  97 +
  98 + @override
  99 + int currentMiddleIndex() {
  100 + return _currentMiddleIndex;
  101 + }
  102 +
  103 + @override
  104 + int currentRightIndex() {
  105 + return _currentRightIndex;
  106 + }
  107 +
  108 + @override
  109 + void setLeftIndex(int index) {
  110 + _currentLeftIndex = index;
  111 + }
  112 +
  113 + @override
  114 + void setMiddleIndex(int index) {
  115 + _currentMiddleIndex = index;
  116 + }
  117 +
  118 + @override
  119 + void setRightIndex(int index) {
  120 + _currentRightIndex = index;
  121 + }
  122 +
  123 + @override
  124 + String leftDivider() {
  125 + return "";
  126 + }
  127 +
  128 + @override
  129 + String rightDivider() {
  130 + return "";
  131 + }
  132 +
  133 + @override
  134 + List<int> layoutProportions() {
  135 + return [3, 3, 3, 2, 2];
  136 + }
  137 +
  138 + @override
  139 + DateTime? finalTime() {
  140 + return null;
  141 + }
  142 +
  143 + @override
  144 + int currentHourIndex() {
  145 + return _currentHourIndex;
  146 + }
  147 +
  148 + @override
  149 + int currentMinuteIndex() {
  150 + return _currentMinuteIndex;
  151 + }
  152 +
  153 + @override
  154 + String? hourStringAtIndex(int index) {
  155 + return null;
  156 + }
  157 +
  158 + @override
  159 + String? minuteStringAtIndex(int index) {
  160 + return null;
  161 + }
  162 +
  163 + @override
  164 + void setHourIndex(int index) {
  165 + _currentHourIndex = index;
  166 + }
  167 +
  168 + @override
  169 + void setMinuteIndex(int index) {
  170 + _currentMinuteIndex = index;
  171 + }
  172 +
  173 + @override
  174 + String timeDivider() {
  175 + return ":";
  176 + }
  177 +}
  178 +
  179 +//a date picker model
  180 +class DatePickerModel extends CommonPickerModel {
  181 + late DateTime maxTime;
  182 + late DateTime minTime;
  183 +
  184 + DatePickerModel({
  185 + DateTime? currentTime,
  186 + DateTime? maxTime,
  187 + DateTime? minTime,
  188 + }) {
  189 + this.maxTime = maxTime ?? DateTime(2049, 12, 31);
  190 + this.minTime = minTime ?? DateTime(1970, 1, 1);
  191 +
  192 + currentTime = currentTime ?? DateTime.now();
  193 +
  194 + if (currentTime.compareTo(this.maxTime) > 0) {
  195 + currentTime = this.maxTime;
  196 + } else if (currentTime.compareTo(this.minTime) < 0) {
  197 + currentTime = this.minTime;
  198 + }
  199 +
  200 + this.currentTime = currentTime;
  201 + _fillLeftLists();
  202 + _fillMiddleLists();
  203 + _fillRightLists();
  204 + int minMonth = _minMonthOfCurrentYear();
  205 + int minDay = _minDayOfCurrentMonth();
  206 + _currentLeftIndex = this.currentTime.year - this.minTime.year;
  207 + _currentMiddleIndex = this.currentTime.month - minMonth;
  208 + _currentRightIndex = this.currentTime.day - minDay;
  209 + _currentHourIndex = this.currentTime.hour;
  210 + _currentMinuteIndex = this.currentTime.minute;
  211 + }
  212 +
  213 + void _fillLeftLists() {
  214 + leftList = List.generate(maxTime.year - minTime.year + 1, (int index) {
  215 + // print('LEFT LIST... ${minTime.year + index}${_localeYear()}');
  216 + return '${minTime.year + index}年';
  217 + });
  218 + }
  219 +
  220 + int _maxMonthOfCurrentYear() {
  221 + return currentTime.year == maxTime.year ? maxTime.month : 12;
  222 + }
  223 +
  224 + int _minMonthOfCurrentYear() {
  225 + return currentTime.year == minTime.year ? minTime.month : 1;
  226 + }
  227 +
  228 + int _maxDayOfCurrentMonth() {
  229 + int dayCount = calcDateCount(currentTime.year, currentTime.month);
  230 + return currentTime.year == maxTime.year &&
  231 + currentTime.month == maxTime.month
  232 + ? maxTime.day
  233 + : dayCount;
  234 + }
  235 +
  236 + int _minDayOfCurrentMonth() {
  237 + return currentTime.year == minTime.year &&
  238 + currentTime.month == minTime.month
  239 + ? minTime.day
  240 + : 1;
  241 + }
  242 +
  243 + void _fillMiddleLists() {
  244 + int minMonth = _minMonthOfCurrentYear();
  245 + int maxMonth = _maxMonthOfCurrentYear();
  246 +
  247 + middleList = List.generate(maxMonth - minMonth + 1, (int index) {
  248 + return '${minMonth + index}月';
  249 + });
  250 + }
  251 +
  252 + void _fillRightLists() {
  253 + int maxDay = _maxDayOfCurrentMonth();
  254 + int minDay = _minDayOfCurrentMonth();
  255 + rightList = List.generate(maxDay - minDay + 1, (int index) {
  256 + return '${minDay + index}日';
  257 + });
  258 + }
  259 +
  260 + @override
  261 + void setLeftIndex(int index) {
  262 + super.setLeftIndex(index);
  263 + //adjust middle
  264 + int destYear = index + minTime.year;
  265 + int minMonth = _minMonthOfCurrentYear();
  266 + DateTime newTime;
  267 + //change date time
  268 + if (currentTime.month == 2 && currentTime.day == 29) {
  269 + newTime = currentTime.isUtc
  270 + ? DateTime.utc(
  271 + destYear,
  272 + currentTime.month,
  273 + calcDateCount(destYear, 2),
  274 + )
  275 + : DateTime(
  276 + destYear,
  277 + currentTime.month,
  278 + calcDateCount(destYear, 2),
  279 + );
  280 + } else {
  281 + newTime = currentTime.isUtc
  282 + ? DateTime.utc(
  283 + destYear,
  284 + currentTime.month,
  285 + currentTime.day,
  286 + )
  287 + : DateTime(
  288 + destYear,
  289 + currentTime.month,
  290 + currentTime.day,
  291 + );
  292 + }
  293 + //min/max check
  294 + if (newTime.isAfter(maxTime)) {
  295 + currentTime = maxTime;
  296 + } else if (newTime.isBefore(minTime)) {
  297 + currentTime = minTime;
  298 + } else {
  299 + currentTime = newTime;
  300 + }
  301 +
  302 + _fillMiddleLists();
  303 + _fillRightLists();
  304 + minMonth = _minMonthOfCurrentYear();
  305 + int minDay = _minDayOfCurrentMonth();
  306 + _currentMiddleIndex = currentTime.month - minMonth;
  307 + _currentRightIndex = currentTime.day - minDay;
  308 + }
  309 +
  310 + @override
  311 + void setMiddleIndex(int index) {
  312 + super.setMiddleIndex(index);
  313 + //adjust right
  314 + int minMonth = _minMonthOfCurrentYear();
  315 + int destMonth = minMonth + index;
  316 + DateTime newTime;
  317 + //change date time
  318 + int dayCount = calcDateCount(currentTime.year, destMonth);
  319 + newTime = currentTime.isUtc
  320 + ? DateTime.utc(
  321 + currentTime.year,
  322 + destMonth,
  323 + currentTime.day <= dayCount ? currentTime.day : dayCount,
  324 + )
  325 + : DateTime(
  326 + currentTime.year,
  327 + destMonth,
  328 + currentTime.day <= dayCount ? currentTime.day : dayCount,
  329 + );
  330 + //min/max check
  331 + if (newTime.isAfter(maxTime)) {
  332 + currentTime = maxTime;
  333 + } else if (newTime.isBefore(minTime)) {
  334 + currentTime = minTime;
  335 + } else {
  336 + currentTime = newTime;
  337 + }
  338 +
  339 + _fillRightLists();
  340 + int minDay = _minDayOfCurrentMonth();
  341 + _currentRightIndex = currentTime.day - minDay;
  342 + }
  343 +
  344 + @override
  345 + void setRightIndex(int index) {
  346 + super.setRightIndex(index);
  347 + int minDay = _minDayOfCurrentMonth();
  348 + currentTime = currentTime.isUtc
  349 + ? DateTime.utc(
  350 + currentTime.year,
  351 + currentTime.month,
  352 + minDay + index,
  353 + )
  354 + : DateTime(
  355 + currentTime.year,
  356 + currentTime.month,
  357 + minDay + index,
  358 + );
  359 + }
  360 +
  361 + @override
  362 + String? leftStringAtIndex(int index) {
  363 + if (index >= 0 && index < leftList.length) {
  364 + return leftList[index];
  365 + } else {
  366 + return null;
  367 + }
  368 + }
  369 +
  370 + @override
  371 + String? middleStringAtIndex(int index) {
  372 + if (index >= 0 && index < middleList.length) {
  373 + return middleList[index];
  374 + } else {
  375 + return null;
  376 + }
  377 + }
  378 +
  379 + @override
  380 + String? rightStringAtIndex(int index) {
  381 + if (index >= 0 && index < rightList.length) {
  382 + return rightList[index];
  383 + } else {
  384 + return null;
  385 + }
  386 + }
  387 +
  388 + @override
  389 + String? hourStringAtIndex(int index) {
  390 + if (index >= 0 && index < 24) {
  391 + return digits(index, 2);
  392 + } else {
  393 + return null;
  394 + }
  395 + }
  396 +
  397 + @override
  398 + String? minuteStringAtIndex(int index) {
  399 + if (index >= 0 && index < 60) {
  400 + return digits(index, 2);
  401 + } else {
  402 + return null;
  403 + }
  404 + }
  405 +
  406 + @override
  407 + DateTime finalTime() {
  408 + return currentTime.isUtc
  409 + ? DateTime.utc(currentTime.year, currentTime.month, currentTime.day,
  410 + _currentHourIndex, _currentMinuteIndex)
  411 + : DateTime(currentTime.year, currentTime.month, currentTime.day,
  412 + _currentHourIndex, _currentMinuteIndex);
  413 + }
  414 +}
  415 +
  416 +class LunarPickerModel extends CommonPickerModel {
  417 + late DateTime maxTime;
  418 + late DateTime minTime;
  419 + late Lunar maxLunarTime;
  420 + late Lunar minLunarTime;
  421 + late Lunar currentLunarTime;
  422 + late bool showLunarYear;
  423 +
  424 + LunarPickerModel(
  425 + {DateTime? currentTime, DateTime? maxTime, DateTime? minTime,bool? showLunarYear = false}) {
  426 + this.maxTime = maxTime ?? DateTime(2049, 12, 31);
  427 + this.minTime = minTime ?? DateTime(1970, 1, 1);
  428 + this.showLunarYear = showLunarYear ?? false;
  429 + currentTime = currentTime ?? DateTime.now();
  430 + // 阳历转阴历
  431 + maxLunarTime = Solar.fromDate(this.maxTime).getLunar();
  432 + minLunarTime = Solar.fromDate(this.minTime).getLunar();
  433 + // 获取当前阴历
  434 + currentLunarTime = Solar.fromDate(currentTime).getLunar();
  435 + debugPrint("currentLunarTime:$currentLunarTime");
  436 + if (currentTime.compareTo(this.maxTime) > 0) {
  437 + currentTime = this.maxTime;
  438 + currentLunarTime = maxLunarTime;
  439 + } else if (currentTime.compareTo(this.minTime) < 0) {
  440 + currentTime = this.minTime;
  441 + currentLunarTime = minLunarTime;
  442 + }
  443 +
  444 + this.currentTime = currentTime;
  445 +
  446 + _fillLeftLists();
  447 + _fillMiddleLists();
  448 + _fillRightLists();
  449 + int minDay = _minDayOfCurrentMonth();
  450 + _currentLeftIndex = currentLunarTime.getYear() - minLunarTime.getYear();
  451 + _currentMiddleIndex = _getCurrentMiddleIndex();
  452 + _currentRightIndex = currentLunarTime.getDay() - minDay;
  453 + _currentHourIndex = this.currentTime.hour;
  454 + _currentMinuteIndex = this.currentTime.minute;
  455 + }
  456 +
  457 + /// 当前年的最大月份
  458 + int _maxMonthOfCurrentYear() {
  459 + return currentLunarTime.getYear() == maxLunarTime.getYear()
  460 + ? maxLunarTime.getMonth()
  461 + : 12;
  462 + }
  463 +
  464 + /// 当前年的最小月份
  465 + int _minMonthOfCurrentYear() {
  466 + return currentLunarTime.getYear() == minLunarTime.getYear()
  467 + ? minLunarTime.getMonth()
  468 + : 1;
  469 + }
  470 +
  471 + /// 当月的最大天数
  472 + int _maxDayOfCurrentMonth() {
  473 + // 当月天数
  474 + int dayCount = LunarMonth.fromYm(
  475 + currentLunarTime.getYear(), currentLunarTime.getMonth())
  476 + ?.getDayCount() ??
  477 + 0;
  478 + return currentLunarTime.getYear() == maxLunarTime.getYear() &&
  479 + currentLunarTime.getMonth() == maxLunarTime.getMonth()
  480 + ? maxLunarTime.getDay()
  481 + : dayCount;
  482 + }
  483 +
  484 + /// 当月的最小天数
  485 + int _minDayOfCurrentMonth() {
  486 + return currentLunarTime.getYear() == minLunarTime.getYear() &&
  487 + currentLunarTime.getMonth() == minLunarTime.getMonth()
  488 + ? minLunarTime.getDay()
  489 + : 1;
  490 + }
  491 +
  492 + void _fillLeftLists() {
  493 + leftList = List.generate(
  494 + maxLunarTime.getYear() - minLunarTime.getYear() + 1, (int index) {
  495 + // print('LEFT LIST... ${minTime.year + index}${_localeYear()}');
  496 + if (showLunarYear) {
  497 + return '${getYearInChinese(minLunarTime.getYear()+index)}年';
  498 + } else {
  499 + return '${minLunarTime.getYear() + index}年';
  500 + }
  501 + });
  502 + }
  503 +
  504 + String getYearInChinese(int year) {
  505 + String y = year.toString();
  506 + String s = '';
  507 + for (int i = 0, j = y.length; i < j; i++) {
  508 + s += LunarUtil.NUMBER[y.codeUnitAt(i) - 48];
  509 + }
  510 + return s;
  511 + }
  512 +
  513 + void _fillMiddleLists() {
  514 + int minMonth = _minMonthOfCurrentYear();
  515 + int maxMonth = _maxMonthOfCurrentYear();
  516 +
  517 + var lunarMonths =
  518 + LunarYear.fromYear(currentLunarTime.getYear()).getMonths();
  519 +
  520 + middleList = [];
  521 +
  522 + // print("--${lunarMonths.length}");
  523 + // 因为农历月份中有闰月所以需要遍历当前所有月份进行查找
  524 + for (var i = 0, j = lunarMonths.length; i < j; i++) {
  525 + // print(lunarMonths[i].toString());
  526 + if (lunarMonths[i].getYear() == currentLunarTime.getYear()) {
  527 + if (currentLunarTime.getYear() == minLunarTime.getYear()) {
  528 + if (i >= minMonth + 1) {
  529 + getLunarMiddleMonth(lunarMonths[i]);
  530 + }
  531 + } else if (currentLunarTime.getYear() == maxLunarTime.getYear()) {
  532 + if (i <= maxMonth + 1) {
  533 + getLunarMiddleMonth(lunarMonths[i]);
  534 + }
  535 + } else {
  536 + getLunarMiddleMonth(lunarMonths[i]);
  537 + }
  538 + }
  539 + }
  540 + // print(this.middleList.length);
  541 + }
  542 +
  543 + /// 检查是否是闰月
  544 + bool isLeap(LunarMonth m) => m.getMonth() < 0;
  545 +
  546 + /// 格式化获取农历月
  547 + getLunarMiddleMonth(LunarMonth m) {
  548 + String month = LunarUtil.MONTH[m.getMonth().abs()];
  549 + middleList.add("${isLeap(m) ? "闰" : ""}$month月");
  550 + }
  551 +
  552 + void _fillRightLists() {
  553 + int maxDay = _maxDayOfCurrentMonth();
  554 + int minDay = _minDayOfCurrentMonth();
  555 + // print("${currentLunarTime.toString()}-${_maxDayOfCurrentMonth()}");
  556 + rightList = List.generate(
  557 + maxDay - minDay + 1 < _maxDayOfCurrentMonth()
  558 + ? maxDay - minDay + 1
  559 + : _maxDayOfCurrentMonth(), (int index) {
  560 + return LunarUtil.DAY[minDay + index];
  561 + });
  562 + }
  563 +
  564 + @override
  565 + void setLeftIndex(int index) {
  566 + super.setLeftIndex(index);
  567 + //adjust middle
  568 + int destYear = index + minLunarTime.getYear();
  569 + DateTime newTime;
  570 +
  571 + // 当月天数
  572 + int dayCount =
  573 + LunarMonth.fromYm(destYear, currentTime.month)?.getDayCount() ?? 0;
  574 + // 当前日期不能大于当月最大天数 & d当前月可能无闰月
  575 + Lunar newLunarTime = Lunar.fromYmd(
  576 + destYear,
  577 + currentLunarTime.getMonth().abs(),
  578 + currentLunarTime.getDay() < dayCount
  579 + ? currentLunarTime.getDay()
  580 + : dayCount);
  581 +
  582 + // 阴历转阳历
  583 + var solarTime = newLunarTime.getSolar();
  584 + newTime =
  585 + DateTime(solarTime.getYear(), solarTime.getMonth(), solarTime.getDay());
  586 +
  587 + // 此处使用阳历进行时间对比,阴历没有
  588 + if (newTime.isAfter(maxTime)) {
  589 + currentTime = maxTime;
  590 + currentLunarTime = maxLunarTime;
  591 + } else if (newTime.isBefore(minTime)) {
  592 + currentTime = minTime;
  593 + currentLunarTime = minLunarTime;
  594 + } else {
  595 + currentTime = newTime;
  596 + currentLunarTime = newLunarTime;
  597 + }
  598 + // print(currentTime);
  599 +
  600 + _fillMiddleLists();
  601 + _fillRightLists();
  602 + int minDay = _minDayOfCurrentMonth();
  603 + _currentMiddleIndex = _getCurrentMiddleIndex();
  604 + _currentRightIndex = currentLunarTime.getDay() - minDay;
  605 + }
  606 +
  607 + //获取当前最小月份指针
  608 + int _getCurrentMiddleIndex() {
  609 + int mCurrentMiddleIndex = 0;
  610 +
  611 + /// 检查是否闰月
  612 + var leapMonth =
  613 + LunarYear.fromYear(currentLunarTime.getYear()).getLeapMonth();
  614 + debugPrint("isLeap:$isLeap");
  615 + debugPrint("当前年最小月份${_minMonthOfCurrentYear()}");
  616 + debugPrint("当前月份${currentLunarTime.getMonth()}");
  617 + // 查询当前月是否存在闰月
  618 + if (leapMonth != 0) {
  619 + // 当前存在闰月
  620 + if (currentLunarTime.getMonth() < 0) {
  621 + // 当前月份为闰月
  622 + mCurrentMiddleIndex =
  623 + currentLunarTime.getMonth().abs() - _minMonthOfCurrentYear() + 1;
  624 + } else {
  625 + if (currentLunarTime.getMonth() > leapMonth) {
  626 + // 如果当前月大于闰月
  627 + mCurrentMiddleIndex =
  628 + currentLunarTime.getMonth().abs() - _minMonthOfCurrentYear() + 1;
  629 + } else {
  630 + mCurrentMiddleIndex =
  631 + currentLunarTime.getMonth().abs() - _minMonthOfCurrentYear();
  632 + }
  633 + }
  634 + } else {
  635 + mCurrentMiddleIndex =
  636 + currentLunarTime.getMonth().abs() - _minMonthOfCurrentYear();
  637 + }
  638 + return mCurrentMiddleIndex;
  639 + }
  640 +
  641 + @override
  642 + void setMiddleIndex(int index) {
  643 + super.setMiddleIndex(index);
  644 + //adjust right
  645 + int minMonth = _minMonthOfCurrentYear();
  646 +
  647 + var d = LunarMonth.fromYm(currentLunarTime.getYear(), minMonth);
  648 + // 往后推x个月
  649 + LunarMonth? nextMonth = d?.next(index);
  650 +
  651 + int dayCount = LunarMonth.fromYm(
  652 + currentLunarTime.getYear(), nextMonth?.getMonth() ?? 0)
  653 + ?.getDayCount() ??
  654 + 0;
  655 +
  656 + Lunar newLunarTime = Lunar.fromYmd(
  657 + currentLunarTime.getYear(),
  658 + nextMonth?.getMonth() ?? 0,
  659 + currentLunarTime.getDay() <= dayCount
  660 + ? currentLunarTime.getDay()
  661 + : dayCount);
  662 +
  663 + DateTime newTime;
  664 + // 阴历转阳历
  665 + var solarTime = newLunarTime.getSolar();
  666 + newTime =
  667 + DateTime(solarTime.getYear(), solarTime.getMonth(), solarTime.getDay());
  668 + //min/max check
  669 + if (newTime.isAfter(maxTime)) {
  670 + currentTime = maxTime;
  671 + currentLunarTime = maxLunarTime;
  672 + } else if (newTime.isBefore(minTime)) {
  673 + currentTime = minTime;
  674 + currentLunarTime = minLunarTime;
  675 + } else {
  676 + currentTime = newTime;
  677 + currentLunarTime = newLunarTime;
  678 + }
  679 +
  680 + _fillRightLists();
  681 + int minDay = _minDayOfCurrentMonth();
  682 + _currentRightIndex = currentLunarTime.getDay() - minDay;
  683 + }
  684 +
  685 + @override
  686 + void setRightIndex(int index) {
  687 + super.setRightIndex(index);
  688 + int minDay = _minDayOfCurrentMonth();
  689 + int maxDay = _maxDayOfCurrentMonth();
  690 +
  691 + ///此处需要注意不能超过本月最大天数
  692 + Lunar newLunarTime = Lunar.fromYmd(
  693 + currentLunarTime.getYear(),
  694 + currentLunarTime.getMonth(),
  695 + (minDay + index <= maxDay) ? minDay + index : maxDay);
  696 + currentLunarTime = newLunarTime;
  697 + // 阴历转阳历
  698 + var solarTime = newLunarTime.getSolar();
  699 + currentTime =
  700 + DateTime(solarTime.getYear(), solarTime.getMonth(), solarTime.getDay());
  701 + }
  702 +
  703 + @override
  704 + String? leftStringAtIndex(int index) {
  705 + if (index >= 0 && index < leftList.length) {
  706 + return leftList[index];
  707 + } else {
  708 + return null;
  709 + }
  710 + }
  711 +
  712 + @override
  713 + String? middleStringAtIndex(int index) {
  714 + if (index >= 0 && index < middleList.length) {
  715 + return middleList[index];
  716 + } else {
  717 + return null;
  718 + }
  719 + }
  720 +
  721 + @override
  722 + String? rightStringAtIndex(int index) {
  723 + if (index >= 0 && index < rightList.length) {
  724 + return rightList[index];
  725 + } else {
  726 + return null;
  727 + }
  728 + }
  729 +
  730 + @override
  731 + String? hourStringAtIndex(int index) {
  732 + if (index >= 0 && index < 24) {
  733 + return digits(index, 2);
  734 + } else {
  735 + return null;
  736 + }
  737 + }
  738 +
  739 + @override
  740 + String? minuteStringAtIndex(int index) {
  741 + if (index >= 0 && index < 60) {
  742 + return digits(index, 2);
  743 + } else {
  744 + return null;
  745 + }
  746 + }
  747 +
  748 + @override
  749 + DateTime finalTime() {
  750 + return currentTime.isUtc
  751 + ? DateTime.utc(currentTime.year, currentTime.month, currentTime.day,
  752 + _currentHourIndex, _currentMinuteIndex)
  753 + : DateTime(currentTime.year, currentTime.month, currentTime.day,
  754 + _currentHourIndex, _currentMinuteIndex);
  755 + }
  756 +
  757 + @override
  758 + List<int> layoutProportions() {
  759 + return [4, 3, 3, 2, 2];
  760 + }
  761 +}
  1 +import 'package:flutter/foundation.dart';
  2 +import 'package:flutter/material.dart';
  3 +
  4 +class DatePickerTheme with DiagnosticableTreeMixin {
  5 + final TextStyle cancelStyle;
  6 + final TextStyle doneStyle;
  7 + final TextStyle itemStyle;
  8 + final Color backgroundColor;
  9 + final Color? headerColor;
  10 +
  11 + final double containerHeight;
  12 + final double titleHeight;
  13 + final double itemHeight;
  14 +
  15 + const DatePickerTheme({
  16 + this.cancelStyle = const TextStyle(color: Colors.black54, fontSize: 16),
  17 + this.doneStyle = const TextStyle(color: Colors.blue, fontSize: 16),
  18 + this.itemStyle = const TextStyle(color: Color(0xFF000046), fontSize: 18),
  19 + this.backgroundColor = Colors.white,
  20 + this.headerColor,
  21 + this.containerHeight = 210.0,
  22 + this.titleHeight = 44.0,
  23 + this.itemHeight = 36.0,
  24 + });
  25 +}
  1 +List<int> _leapYearMonths = const <int>[1, 3, 5, 7, 8, 10, 12];
  2 +
  3 +int calcDateCount(int year, int month) {
  4 + if (_leapYearMonths.contains(month)) {
  5 + return 31;
  6 + } else if (month == 2) {
  7 + if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
  8 + return 29;
  9 + }
  10 + return 28;
  11 + }
  12 + return 30;
  13 +}
  1 +library flutter_lunar_datetime_picker;
  2 +
  3 +import 'package:flutter/cupertino.dart';
  4 +import 'package:flutter/material.dart';
  5 +import 'package:flutter_lunar_datetime_picker/date_init.dart';
  6 +import 'package:flutter_lunar_datetime_picker/date_model.dart';
  7 +import 'package:flutter_lunar_datetime_picker/datetime_picker_theme.dart'
  8 + as picker_theme;
  9 +
  10 +typedef DateChangedCallback = Function(DateTime time, bool lunar);
  11 +typedef DateCancelledCallback = Function();
  12 +typedef StringAtIndexCallBack = String? Function(int index);
  13 +
  14 +class DatePicker {
  15 + ///
  16 + /// Display date picker bottom sheet.
  17 + ///
  18 + static Future<DateTime?> showDatePicker(
  19 + BuildContext context, {
  20 + bool showTitleActions = true,
  21 + DateTime? minTime,
  22 + DateTime? maxTime,
  23 + DateChangedCallback? onChanged,
  24 + DateChangedCallback? onConfirm,
  25 + DateCancelledCallback? onCancel,
  26 + DateTime? currentTime,
  27 + picker_theme.DatePickerTheme? theme,
  28 + bool? lunarPicker,
  29 + DateInitTime? dateInitTime,
  30 + bool? showTime,
  31 + bool? showLunarYear,
  32 + }) async {
  33 + return await Navigator.push(
  34 + context,
  35 + _DatePickerRoute(
  36 + showTitleActions: showTitleActions,
  37 + onChanged: onChanged,
  38 + onConfirm: onConfirm,
  39 + onCancel: onCancel,
  40 + theme: theme,
  41 + lunarPicker: lunarPicker,
  42 + dateInitTime: dateInitTime,
  43 + barrierLabel:
  44 + MaterialLocalizations.of(context).modalBarrierDismissLabel,
  45 + showTime: showTime,
  46 + showLunarYear: showLunarYear,
  47 + ),
  48 + );
  49 + }
  50 +}
  51 +
  52 +class _DatePickerRoute<T> extends PopupRoute<T> {
  53 + _DatePickerRoute({
  54 + this.showTitleActions,
  55 + this.onChanged,
  56 + this.onConfirm,
  57 + this.onCancel,
  58 + this.lunarPicker,
  59 + picker_theme.DatePickerTheme? theme,
  60 + this.dateInitTime,
  61 + this.barrierLabel,
  62 + this.showTime,
  63 + this.showLunarYear,
  64 + RouteSettings? settings,
  65 + }) : theme = theme ?? const picker_theme.DatePickerTheme(),
  66 + super(settings: settings);
  67 +
  68 + final bool? showTitleActions;
  69 + final DateChangedCallback? onChanged;
  70 + final DateChangedCallback? onConfirm;
  71 + final DateCancelledCallback? onCancel;
  72 + final picker_theme.DatePickerTheme theme;
  73 + final bool? lunarPicker;
  74 + final DateInitTime? dateInitTime;
  75 + final bool? showTime;
  76 + final bool? showLunarYear;
  77 +
  78 + @override
  79 + Duration get transitionDuration => const Duration(milliseconds: 200);
  80 +
  81 + @override
  82 + bool get barrierDismissible => true;
  83 +
  84 + @override
  85 + final String? barrierLabel;
  86 +
  87 + @override
  88 + Color get barrierColor => Colors.black54;
  89 +
  90 + AnimationController? _animationController;
  91 +
  92 + @override
  93 + AnimationController createAnimationController() {
  94 + assert(_animationController == null);
  95 + _animationController =
  96 + BottomSheet.createAnimationController(navigator!.overlay!);
  97 + return _animationController!;
  98 + }
  99 +
  100 + @override
  101 + Widget buildPage(BuildContext context, Animation<double> animation,
  102 + Animation<double> secondaryAnimation) {
  103 + Widget bottomSheet = MediaQuery.removePadding(
  104 + context: context,
  105 + removeTop: true,
  106 + child: _DatePickerComponent(
  107 + onChanged: onChanged,
  108 + route: this,
  109 + lunarPicker: lunarPicker ?? false,
  110 + dateInitTime: dateInitTime,
  111 + showTime: showTime,
  112 + showLunarYear: showLunarYear ?? false,
  113 + ),
  114 + );
  115 + return InheritedTheme.captureAll(context, bottomSheet);
  116 + }
  117 +}
  118 +
  119 +class _DatePickerComponent extends StatefulWidget {
  120 + const _DatePickerComponent({
  121 + Key? key,
  122 + required this.route,
  123 + this.onChanged,
  124 + required this.lunarPicker,
  125 + required this.dateInitTime,
  126 + required this.showTime,
  127 + required this.showLunarYear,
  128 + }) : super(key: key);
  129 +
  130 + final DateChangedCallback? onChanged;
  131 +
  132 + final _DatePickerRoute route;
  133 +
  134 + final bool lunarPicker;
  135 +
  136 + final DateInitTime? dateInitTime;
  137 +
  138 + final bool? showTime;
  139 +
  140 + final bool? showLunarYear;
  141 +
  142 + @override
  143 + State<StatefulWidget> createState() {
  144 + return _DatePickerState();
  145 + }
  146 +}
  147 +
  148 +class _DatePickerState extends State<_DatePickerComponent> {
  149 + late FixedExtentScrollController leftScrollCtrl,
  150 + middleScrollCtrl,
  151 + rightScrollCtrl,
  152 + hourScrollCtrl,
  153 + minuteScrollCtrl;
  154 +
  155 + bool lunarPicker = false;
  156 +
  157 + late BasePickerModel pickerModel;
  158 +
  159 + @override
  160 + void initState() {
  161 + super.initState();
  162 + // 是否阴历
  163 + lunarPicker = widget.lunarPicker;
  164 + if (lunarPicker) {
  165 + pickerModel = LunarPickerModel(
  166 + currentTime: widget.dateInitTime?.currentTime,
  167 + maxTime: widget.dateInitTime?.maxTime,
  168 + minTime: widget.dateInitTime?.minTime,
  169 + showLunarYear: widget.showLunarYear,
  170 + );
  171 + } else {
  172 + pickerModel = DatePickerModel(
  173 + currentTime: widget.dateInitTime?.currentTime,
  174 + maxTime: widget.dateInitTime?.maxTime,
  175 + minTime: widget.dateInitTime?.minTime);
  176 + }
  177 + refreshScrollOffset();
  178 + }
  179 +
  180 + void onLunarChange(bool lunarPicker) {
  181 + setState(() {
  182 + this.lunarPicker = lunarPicker;
  183 + debugPrint("切换类型:${pickerModel.finalTime().toString()}");
  184 + pickerModel = lunarPicker
  185 + ? LunarPickerModel(
  186 + currentTime: pickerModel.finalTime(),
  187 + maxTime: widget.dateInitTime?.maxTime,
  188 + minTime: widget.dateInitTime?.minTime,
  189 + showLunarYear: widget.showLunarYear)
  190 + : DatePickerModel(
  191 + currentTime: pickerModel.finalTime(),
  192 + maxTime: widget.dateInitTime?.maxTime,
  193 + minTime: widget.dateInitTime?.minTime);
  194 + });
  195 + refreshScrollOffset();
  196 + _notifyDateChanged();
  197 + }
  198 +
  199 + void refreshScrollOffset() {
  200 + // debugPrint('refreshScrollOffset ${pickerModel.currentMiddleIndex()}');
  201 + leftScrollCtrl = FixedExtentScrollController(
  202 + initialItem: pickerModel.currentLeftIndex());
  203 + middleScrollCtrl = FixedExtentScrollController(
  204 + initialItem: pickerModel.currentMiddleIndex());
  205 + rightScrollCtrl = FixedExtentScrollController(
  206 + initialItem: pickerModel.currentRightIndex());
  207 + hourScrollCtrl = FixedExtentScrollController(
  208 + initialItem: pickerModel.currentHourIndex());
  209 + minuteScrollCtrl = FixedExtentScrollController(
  210 + initialItem: pickerModel.currentMinuteIndex());
  211 + }
  212 +
  213 + @override
  214 + void dispose() {
  215 + leftScrollCtrl.dispose();
  216 + middleScrollCtrl.dispose();
  217 + rightScrollCtrl.dispose();
  218 + hourScrollCtrl.dispose();
  219 + minuteScrollCtrl.dispose();
  220 + super.dispose();
  221 + }
  222 +
  223 + @override
  224 + Widget build(BuildContext context) {
  225 + picker_theme.DatePickerTheme theme = widget.route.theme;
  226 + return GestureDetector(
  227 + child: AnimatedBuilder(
  228 + animation: widget.route.animation!,
  229 + builder: (BuildContext context, Widget? child) {
  230 + final double bottomPadding = MediaQuery.of(context).padding.bottom;
  231 + return ClipRect(
  232 + child: CustomSingleChildLayout(
  233 + delegate: _BottomPickerLayout(
  234 + widget.route.animation!.value,
  235 + theme,
  236 + showTitleActions: widget.route.showTitleActions!,
  237 + bottomPadding: bottomPadding,
  238 + ),
  239 + child: GestureDetector(
  240 + child: Material(
  241 + color: theme.backgroundColor,
  242 + child: _renderPickerView(theme),
  243 + ),
  244 + ),
  245 + ),
  246 + );
  247 + },
  248 + ),
  249 + );
  250 + }
  251 +
  252 + void _notifyDateChanged() {
  253 + if (widget.onChanged != null) {
  254 + widget.onChanged!(pickerModel.finalTime()!, lunarPicker);
  255 + }
  256 + }
  257 +
  258 + Widget _renderPickerView(picker_theme.DatePickerTheme theme) {
  259 + Widget itemView = _renderItemView(theme);
  260 + if (widget.route.showTitleActions == true) {
  261 + return Column(
  262 + children: <Widget>[
  263 + _renderTitleActionsView(theme),
  264 + itemView,
  265 + ],
  266 + );
  267 + }
  268 + return itemView;
  269 + }
  270 +
  271 + Widget _renderColumnView(
  272 + ValueKey key,
  273 + picker_theme.DatePickerTheme theme,
  274 + StringAtIndexCallBack stringAtIndexCB,
  275 + ScrollController scrollController,
  276 + int layoutProportion,
  277 + ValueChanged<int> selectedChangedWhenScrolling,
  278 + ValueChanged<int> selectedChangedWhenScrollEnd,
  279 + ) {
  280 + return Expanded(
  281 + flex: layoutProportion,
  282 + child: Container(
  283 + // padding: const EdgeInsets.all(2.0),
  284 + height: theme.containerHeight,
  285 + decoration: BoxDecoration(color: theme.backgroundColor),
  286 + child: NotificationListener(
  287 + onNotification: (ScrollNotification notification) {
  288 + if (notification.depth == 0 &&
  289 + notification is ScrollEndNotification &&
  290 + notification.metrics is FixedExtentMetrics) {
  291 + final FixedExtentMetrics metrics =
  292 + notification.metrics as FixedExtentMetrics;
  293 + final int currentItemIndex = metrics.itemIndex;
  294 + selectedChangedWhenScrollEnd(currentItemIndex);
  295 + }
  296 + return false;
  297 + },
  298 + child: CupertinoPicker.builder(
  299 + key: key,
  300 + backgroundColor: theme.backgroundColor,
  301 + scrollController: scrollController as FixedExtentScrollController,
  302 + itemExtent: theme.itemHeight,
  303 + onSelectedItemChanged: (int index) {
  304 + selectedChangedWhenScrolling(index);
  305 + },
  306 + useMagnifier: false,
  307 + itemBuilder: (BuildContext context, int index) {
  308 + final content = stringAtIndexCB(index);
  309 + if (content == null) {
  310 + return null;
  311 + }
  312 + return Container(
  313 + height: theme.itemHeight,
  314 + alignment: Alignment.center,
  315 + child: Text(
  316 + content,
  317 + style: theme.itemStyle,
  318 + textAlign: TextAlign.start,
  319 + ),
  320 + );
  321 + },
  322 + ),
  323 + ),
  324 + ),
  325 + );
  326 + }
  327 +
  328 + Widget _renderItemView(picker_theme.DatePickerTheme theme) {
  329 + return Container(
  330 + color: theme.backgroundColor,
  331 + child: Directionality(
  332 + textDirection: TextDirection.ltr,
  333 + child: Row(
  334 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  335 + children: <Widget>[
  336 + // 年
  337 + Container(
  338 + child: pickerModel.layoutProportions()[0] > 0
  339 + ? _renderColumnView(
  340 + ValueKey(pickerModel.currentLeftIndex()),
  341 + theme,
  342 + pickerModel.leftStringAtIndex,
  343 + leftScrollCtrl,
  344 + pickerModel.layoutProportions()[0], (index) {
  345 + pickerModel.setLeftIndex(index);
  346 + }, (index) {
  347 + setState(() {
  348 + refreshScrollOffset();
  349 + _notifyDateChanged();
  350 + });
  351 + })
  352 + : null,
  353 + ),
  354 + Text(
  355 + pickerModel.leftDivider(),
  356 + style: theme.itemStyle,
  357 + ),
  358 + // 月
  359 + Container(
  360 + child: pickerModel.layoutProportions()[1] > 0
  361 + ? _renderColumnView(
  362 + ValueKey(pickerModel.currentLeftIndex() * 100 +
  363 + pickerModel.currentMiddleIndex()),
  364 + theme,
  365 + pickerModel.middleStringAtIndex,
  366 + middleScrollCtrl,
  367 + pickerModel.layoutProportions()[1], (index) {
  368 + pickerModel.setMiddleIndex(index);
  369 + }, (index) {
  370 + debugPrint('index: $index');
  371 + setState(() {
  372 + refreshScrollOffset();
  373 + _notifyDateChanged();
  374 + });
  375 + })
  376 + : null,
  377 + ),
  378 + Text(
  379 + pickerModel.rightDivider(),
  380 + style: theme.itemStyle,
  381 + ),
  382 + // 日
  383 + Container(
  384 + child: pickerModel.layoutProportions()[2] > 0
  385 + ? _renderColumnView(
  386 + ValueKey(pickerModel.currentMiddleIndex() * 100 +
  387 + pickerModel.currentLeftIndex()),
  388 + theme,
  389 + pickerModel.rightStringAtIndex,
  390 + rightScrollCtrl,
  391 + pickerModel.layoutProportions()[2], (index) {
  392 + pickerModel.setRightIndex(index);
  393 + }, (index) {
  394 + setState(() {
  395 + refreshScrollOffset();
  396 + _notifyDateChanged();
  397 + });
  398 + })
  399 + : null,
  400 + ),
  401 + if (widget.showTime ?? true)
  402 + Text(
  403 + pickerModel.rightDivider(),
  404 + style: theme.itemStyle,
  405 + ),
  406 + if (widget.showTime ?? true)
  407 + Container(
  408 + child: pickerModel.layoutProportions()[3] > 0
  409 + ? _renderColumnView(
  410 + ValueKey(pickerModel.currentMinuteIndex() * 200 +
  411 + pickerModel.currentHourIndex()),
  412 + theme,
  413 + pickerModel.hourStringAtIndex,
  414 + hourScrollCtrl,
  415 + pickerModel.layoutProportions()[3], (index) {
  416 + pickerModel.setHourIndex(index);
  417 + }, (index) {
  418 + setState(() {
  419 + refreshScrollOffset();
  420 + _notifyDateChanged();
  421 + });
  422 + })
  423 + : null,
  424 + ),
  425 + if (widget.showTime ?? true)
  426 + Text(
  427 + pickerModel.timeDivider(),
  428 + style: theme.itemStyle,
  429 + ),
  430 + if (widget.showTime ?? true)
  431 + Container(
  432 + child: pickerModel.layoutProportions()[4] > 0
  433 + ? _renderColumnView(
  434 + ValueKey(pickerModel.currentMinuteIndex() * 100 +
  435 + pickerModel.currentHourIndex()),
  436 + theme,
  437 + pickerModel.minuteStringAtIndex,
  438 + minuteScrollCtrl,
  439 + pickerModel.layoutProportions()[4], (index) {
  440 + pickerModel.setMinuteIndex(index);
  441 + }, (index) {
  442 + setState(() {
  443 + refreshScrollOffset();
  444 + _notifyDateChanged();
  445 + });
  446 + })
  447 + : null,
  448 + ),
  449 + ],
  450 + ),
  451 + ),
  452 + );
  453 + }
  454 +
  455 + // Title View
  456 + Widget _renderTitleActionsView(picker_theme.DatePickerTheme theme) {
  457 + const done = "完成";
  458 + const cancel = "取消";
  459 +
  460 + return Container(
  461 + height: theme.titleHeight,
  462 + decoration: BoxDecoration(
  463 + color: theme.headerColor ?? theme.backgroundColor,
  464 + ),
  465 + child: Row(
  466 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  467 + children: <Widget>[
  468 + SizedBox(
  469 + height: theme.titleHeight,
  470 + child: CupertinoButton(
  471 + pressedOpacity: 0.3,
  472 + padding: const EdgeInsetsDirectional.only(start: 16, top: 0),
  473 + child: Text(
  474 + cancel,
  475 + style: theme.cancelStyle,
  476 + ),
  477 + onPressed: () {
  478 + Navigator.pop(context);
  479 + if (widget.route.onCancel != null) {
  480 + widget.route.onCancel!();
  481 + }
  482 + },
  483 + ),
  484 + ),
  485 + // Container(
  486 + // decoration: BoxDecoration(
  487 + // border: Border.all(width: 1, color: theme.doneStyle.color!),
  488 + // borderRadius: const BorderRadius.all(Radius.circular(8.0)),
  489 + // ),
  490 + // child: Row(
  491 + // children: [
  492 + // TextButton(
  493 + // onPressed: () {
  494 + // onLunarChange(false);
  495 + // },
  496 + // style: ButtonStyle(
  497 + // shape: MaterialStateProperty.all(
  498 + // const RoundedRectangleBorder(
  499 + // borderRadius: BorderRadius.only(
  500 + // topLeft: Radius.circular(7),
  501 + // bottomLeft: Radius.circular(7),
  502 + // ),
  503 + // )),
  504 + // padding: MaterialStateProperty.all(EdgeInsets.zero),
  505 + // tapTargetSize: MaterialTapTargetSize.shrinkWrap,
  506 + // minimumSize:
  507 + // MaterialStateProperty.all(const Size(50, 26)),
  508 + // backgroundColor: lunarPicker
  509 + // ? MaterialStateProperty.all(Colors.transparent)
  510 + // : MaterialStateProperty.all(theme.doneStyle.color)),
  511 + // child: Text(
  512 + // "公历",
  513 + // style: TextStyle(
  514 + // color:
  515 + // lunarPicker ? theme.doneStyle.color : Colors.white),
  516 + // ),
  517 + // ),
  518 + // TextButton(
  519 + // onPressed: () {
  520 + // onLunarChange(true);
  521 + // },
  522 + // style: ButtonStyle(
  523 + // shape: MaterialStateProperty.all(const RoundedRectangleBorder(
  524 + // borderRadius: BorderRadius.only(
  525 + // topRight: Radius.circular(7),
  526 + // bottomRight: Radius.circular(7),
  527 + // ),)),
  528 + // padding: MaterialStateProperty.all(EdgeInsets.zero),
  529 + // tapTargetSize: MaterialTapTargetSize.shrinkWrap,
  530 + // minimumSize:
  531 + // MaterialStateProperty.all(const Size(50, 26)),
  532 + // backgroundColor: lunarPicker
  533 + // ? MaterialStateProperty.all(theme.doneStyle.color)
  534 + // : MaterialStateProperty.all(Colors.transparent)),
  535 + // child: Text("阴历",
  536 + // style: TextStyle(
  537 + // color: lunarPicker
  538 + // ? Colors.white
  539 + // : theme.doneStyle.color)),
  540 + // ),
  541 + // ],
  542 + // ),
  543 + // ),
  544 + SizedBox(
  545 + height: theme.titleHeight,
  546 + child: CupertinoButton(
  547 + pressedOpacity: 0.3,
  548 + padding: const EdgeInsetsDirectional.only(end: 16, top: 0),
  549 + child: Text(
  550 + done,
  551 + style: theme.doneStyle,
  552 + ),
  553 + onPressed: () {
  554 + Navigator.pop(context, pickerModel.finalTime());
  555 + if (widget.route.onConfirm != null) {
  556 + widget.route.onConfirm!(
  557 + pickerModel.finalTime()!, lunarPicker);
  558 + }
  559 + },
  560 + ),
  561 + ),
  562 + ],
  563 + ),
  564 + );
  565 + }
  566 +}
  567 +
  568 +class _BottomPickerLayout extends SingleChildLayoutDelegate {
  569 + _BottomPickerLayout(
  570 + this.progress,
  571 + this.theme, {
  572 + this.showTitleActions,
  573 + this.bottomPadding = 0,
  574 + });
  575 +
  576 + final double progress;
  577 +
  578 + // final int? itemCount;
  579 + final bool? showTitleActions;
  580 + final picker_theme.DatePickerTheme theme;
  581 + final double bottomPadding;
  582 +
  583 + @override
  584 + BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
  585 + double maxHeight = theme.containerHeight;
  586 + if (showTitleActions == true) {
  587 + maxHeight += theme.titleHeight;
  588 + }
  589 +
  590 + return BoxConstraints(
  591 + minWidth: constraints.maxWidth,
  592 + maxWidth: constraints.maxWidth,
  593 + minHeight: 0.0,
  594 + maxHeight: maxHeight + bottomPadding,
  595 + );
  596 + }
  597 +
  598 + @override
  599 + Offset getPositionForChild(Size size, Size childSize) {
  600 + final height = size.height - childSize.height * progress;
  601 + return Offset(0.0, height);
  602 + }
  603 +
  604 + @override
  605 + bool shouldRelayout(_BottomPickerLayout oldDelegate) {
  606 + return progress != oldDelegate.progress;
  607 + }
  608 +}
  1 +# Generated by pub
  2 +# See https://dart.dev/tools/pub/glossary#lockfile
  3 +packages:
  4 + async:
  5 + dependency: transitive
  6 + description:
  7 + name: async
  8 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
  9 + url: "https://pub.flutter-io.cn"
  10 + source: hosted
  11 + version: "2.11.0"
  12 + boolean_selector:
  13 + dependency: transitive
  14 + description:
  15 + name: boolean_selector
  16 + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
  17 + url: "https://pub.flutter-io.cn"
  18 + source: hosted
  19 + version: "2.1.1"
  20 + characters:
  21 + dependency: transitive
  22 + description:
  23 + name: characters
  24 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
  25 + url: "https://pub.flutter-io.cn"
  26 + source: hosted
  27 + version: "1.3.0"
  28 + clock:
  29 + dependency: transitive
  30 + description:
  31 + name: clock
  32 + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
  33 + url: "https://pub.flutter-io.cn"
  34 + source: hosted
  35 + version: "1.1.1"
  36 + collection:
  37 + dependency: transitive
  38 + description:
  39 + name: collection
  40 + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
  41 + url: "https://pub.flutter-io.cn"
  42 + source: hosted
  43 + version: "1.19.0"
  44 + fake_async:
  45 + dependency: transitive
  46 + description:
  47 + name: fake_async
  48 + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
  49 + url: "https://pub.flutter-io.cn"
  50 + source: hosted
  51 + version: "1.3.1"
  52 + flutter:
  53 + dependency: "direct main"
  54 + description: flutter
  55 + source: sdk
  56 + version: "0.0.0"
  57 + flutter_lints:
  58 + dependency: "direct dev"
  59 + description:
  60 + name: flutter_lints
  61 + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
  62 + url: "https://pub.flutter-io.cn"
  63 + source: hosted
  64 + version: "2.0.3"
  65 + flutter_test:
  66 + dependency: "direct dev"
  67 + description: flutter
  68 + source: sdk
  69 + version: "0.0.0"
  70 + leak_tracker:
  71 + dependency: transitive
  72 + description:
  73 + name: leak_tracker
  74 + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
  75 + url: "https://pub.flutter-io.cn"
  76 + source: hosted
  77 + version: "10.0.7"
  78 + leak_tracker_flutter_testing:
  79 + dependency: transitive
  80 + description:
  81 + name: leak_tracker_flutter_testing
  82 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
  83 + url: "https://pub.flutter-io.cn"
  84 + source: hosted
  85 + version: "3.0.8"
  86 + leak_tracker_testing:
  87 + dependency: transitive
  88 + description:
  89 + name: leak_tracker_testing
  90 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
  91 + url: "https://pub.flutter-io.cn"
  92 + source: hosted
  93 + version: "3.0.1"
  94 + lints:
  95 + dependency: transitive
  96 + description:
  97 + name: lints
  98 + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
  99 + url: "https://pub.flutter-io.cn"
  100 + source: hosted
  101 + version: "2.1.1"
  102 + lunar:
  103 + dependency: "direct main"
  104 + description:
  105 + name: lunar
  106 + sha256: "4ebb40c1647c5903fc67ff0be09a4ce90da79b482f0c78a8c727086a67375c37"
  107 + url: "https://pub.flutter-io.cn"
  108 + source: hosted
  109 + version: "1.7.5"
  110 + matcher:
  111 + dependency: transitive
  112 + description:
  113 + name: matcher
  114 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
  115 + url: "https://pub.flutter-io.cn"
  116 + source: hosted
  117 + version: "0.12.16+1"
  118 + material_color_utilities:
  119 + dependency: transitive
  120 + description:
  121 + name: material_color_utilities
  122 + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
  123 + url: "https://pub.flutter-io.cn"
  124 + source: hosted
  125 + version: "0.11.1"
  126 + meta:
  127 + dependency: transitive
  128 + description:
  129 + name: meta
  130 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
  131 + url: "https://pub.flutter-io.cn"
  132 + source: hosted
  133 + version: "1.15.0"
  134 + path:
  135 + dependency: transitive
  136 + description:
  137 + name: path
  138 + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
  139 + url: "https://pub.flutter-io.cn"
  140 + source: hosted
  141 + version: "1.9.0"
  142 + sky_engine:
  143 + dependency: transitive
  144 + description: flutter
  145 + source: sdk
  146 + version: "0.0.0"
  147 + source_span:
  148 + dependency: transitive
  149 + description:
  150 + name: source_span
  151 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
  152 + url: "https://pub.flutter-io.cn"
  153 + source: hosted
  154 + version: "1.10.0"
  155 + stack_trace:
  156 + dependency: transitive
  157 + description:
  158 + name: stack_trace
  159 + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
  160 + url: "https://pub.flutter-io.cn"
  161 + source: hosted
  162 + version: "1.12.0"
  163 + stream_channel:
  164 + dependency: transitive
  165 + description:
  166 + name: stream_channel
  167 + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
  168 + url: "https://pub.flutter-io.cn"
  169 + source: hosted
  170 + version: "2.1.2"
  171 + string_scanner:
  172 + dependency: transitive
  173 + description:
  174 + name: string_scanner
  175 + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
  176 + url: "https://pub.flutter-io.cn"
  177 + source: hosted
  178 + version: "1.3.0"
  179 + term_glyph:
  180 + dependency: transitive
  181 + description:
  182 + name: term_glyph
  183 + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
  184 + url: "https://pub.flutter-io.cn"
  185 + source: hosted
  186 + version: "1.2.1"
  187 + test_api:
  188 + dependency: transitive
  189 + description:
  190 + name: test_api
  191 + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
  192 + url: "https://pub.flutter-io.cn"
  193 + source: hosted
  194 + version: "0.7.3"
  195 + vector_math:
  196 + dependency: transitive
  197 + description:
  198 + name: vector_math
  199 + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
  200 + url: "https://pub.flutter-io.cn"
  201 + source: hosted
  202 + version: "2.1.4"
  203 + vm_service:
  204 + dependency: transitive
  205 + description:
  206 + name: vm_service
  207 + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
  208 + url: "https://pub.flutter-io.cn"
  209 + source: hosted
  210 + version: "14.3.0"
  211 +sdks:
  212 + dart: ">=3.4.0 <4.0.0"
  213 + flutter: ">=3.18.0-18.0.pre.54"
  1 +name: flutter_lunar_datetime_picker
  2 +description: A Flutter Lunar Datetime Picker ! You can dynamically switch the selection of the lunar calendar and lunar calendar.
  3 +version: 1.0.6
  4 +homepage: https://github.com/LoquatZ/flutter_lunar_datetime_picker
  5 +
  6 +environment:
  7 + sdk: '>=2.12.0 <4.0.0'
  8 + flutter: ">=1.17.0"
  9 +
  10 +dependencies:
  11 + flutter:
  12 + sdk: flutter
  13 + lunar: ^1.2.21
  14 +
  15 +dev_dependencies:
  16 + flutter_test:
  17 + sdk: flutter
  18 + flutter_lints: ^2.0.0
  19 +
  20 +
  21 +# For information on the generic Dart part of this file, see the
  22 +# following page: https://dart.dev/tools/pub/pubspec
  23 +
  24 +# The following section is specific to Flutter packages.
  25 +flutter:
  26 +
  27 + # To add assets to your package, add an assets section, like this:
  28 + # assets:
  29 + # - images/a_dot_burr.jpeg
  30 + # - images/a_dot_ham.jpeg
  31 + #
  32 + # For details regarding assets in packages, see
  33 + # https://flutter.dev/assets-and-images/#from-packages
  34 + #
  35 + # An image asset can refer to one or more resolution-specific "variants", see
  36 + # https://flutter.dev/assets-and-images/#resolution-aware
  37 +
  38 + # To add custom fonts to your package, add a fonts section here,
  39 + # in this "flutter" section. Each entry in this list should have a
  40 + # "family" key with the font family name, and a "fonts" key with a
  41 + # list giving the asset and other descriptors for the font. For
  42 + # example:
  43 + # fonts:
  44 + # - family: Schyler
  45 + # fonts:
  46 + # - asset: fonts/Schyler-Regular.ttf
  47 + # - asset: fonts/Schyler-Italic.ttf
  48 + # style: italic
  49 + # - family: Trajan Pro
  50 + # fonts:
  51 + # - asset: fonts/TrajanPro.ttf
  52 + # - asset: fonts/TrajanPro_Bold.ttf
  53 + # weight: 700
  54 + #
  55 + # For details regarding fonts in packages, see
  56 + # https://flutter.dev/custom-fonts/#from-packages
  1 +import 'package:flutter_test/flutter_test.dart';
  2 +
  3 +void main() {
  4 + test('adds one to input values', () {
  5 +
  6 + });
  7 +}
@@ -845,6 +845,13 @@ packages: @@ -845,6 +845,13 @@ packages:
845 description: flutter 845 description: flutter
846 source: sdk 846 source: sdk
847 version: "0.0.0" 847 version: "0.0.0"
  848 + flutter_lunar_datetime_picker:
  849 + dependency: "direct main"
  850 + description:
  851 + path: "library/flutter_lunar_datetime_picker-1.0.6"
  852 + relative: true
  853 + source: path
  854 + version: "1.0.6"
848 flutter_native_contact_picker: 855 flutter_native_contact_picker:
849 dependency: "direct main" 856 dependency: "direct main"
850 description: 857 description:
@@ -1215,6 +1222,14 @@ packages: @@ -1215,6 +1222,14 @@ packages:
1215 url: "https://pub.flutter-io.cn" 1222 url: "https://pub.flutter-io.cn"
1216 source: hosted 1223 source: hosted
1217 version: "2.0.3" 1224 version: "2.0.3"
  1225 + lunar:
  1226 + dependency: transitive
  1227 + description:
  1228 + name: lunar
  1229 + sha256: "4ebb40c1647c5903fc67ff0be09a4ce90da79b482f0c78a8c727086a67375c37"
  1230 + url: "https://pub.flutter-io.cn"
  1231 + source: hosted
  1232 + version: "1.7.5"
1218 macros: 1233 macros:
1219 dependency: transitive 1234 dependency: transitive
1220 description: 1235 description:
@@ -241,6 +241,9 @@ dependencies: @@ -241,6 +241,9 @@ dependencies:
241 azlistview_plus: 241 azlistview_plus:
242 path: library/azlistview_plus-3.0.0 242 path: library/azlistview_plus-3.0.0
243 243
  244 + flutter_lunar_datetime_picker:
  245 + path: library/flutter_lunar_datetime_picker-1.0.6
  246 +
244 247
245 248
246 249
@@ -304,6 +307,8 @@ dependencies: @@ -304,6 +307,8 @@ dependencies:
304 #表格多选组建 307 #表格多选组建
305 # flutter_awesome_select: ^6.5.0 308 # flutter_awesome_select: ^6.5.0
306 collection: ^1.15.0-nullsafety.4 309 collection: ^1.15.0-nullsafety.4
  310 +
  311 +
307 312
308 313
309 314