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>
}
getSellerVersion() async {
await collectStoreProvider.getSellerVersion(context);
await collectStoreProvider.getSellerVersion(context,showLoading: false);
setState(() {});
}
... ...
... ... @@ -992,13 +992,13 @@ class _CustomerDetailPageState extends State<CustomerDetailPage> {
color: MyColours.color_333333),
),
Spacer(),
Text(
birthday,
style: TextStyle(
fontSize: ScreenUtil().setSp(26),
color: MyColours.color_333333),
),
HEmptyView(20),
// Text(
// birthday,
// style: TextStyle(
// fontSize: ScreenUtil().setSp(26),
// color: MyColours.color_333333),
// ),
// HEmptyView(20),
RoundButton(
text: '编辑',
radius: ScreenUtil().setWidth(20),
... ... @@ -1007,42 +1007,9 @@ class _CustomerDetailPageState extends State<CustomerDetailPage> {
fontSize: 26,
isBold: false,
onPressed: () {
DialogUtil.showPickerDateTime24(
context,
scaffoldKey,
(value) async {
// {'text': picker.adapter.text, 'select': selecteds}
if (value != null) {
setState(() {
print(value);
birthday = DateUtil.formatDateStr(value,
format: DateFormats.y_mo_d);
});
// 请求接口,设置生日
String from = birthday + ' 00:00:00';
Map<String, String?> params = {
'id': widget.userHistoryEntity!.gid,
'c_day':
'${(DateUtil.getDateMsByTimeStr(from)! / 1000).floor()}',
};
bool sucess = await customerProvider
.setGuestInfo(context, params,
showLoading: true);
if (sucess) {
Utils.showToast('保存成功');
}
}
// showDateSelWidget = false;
},
yearBegin: 1925,
minValue: DateTime(1925),
dateTime: birthday == ''
? DateTime.now()
: DateUtil.getDateTime(birthday),
pickerDateTimeType: PickerDateTimeType.kYMD,
onCancel: () {
// showDateSelWidget = false;
});
NavigatorUtil.goSetBirthdayPage(context,widget.userHistoryEntity!.gid);
},
),
],
... ...
... ... @@ -266,7 +266,7 @@ class _CustomerListPageState extends State<CustomerListPage>
}
getSellerVersion() async {
await collectStoreProvider.getSellerVersion(context);
await collectStoreProvider.getSellerVersion(context,showLoading: false);
setState(() {});
}
... ...
import 'package:common_utils/common_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_lunar_datetime_picker/date_init.dart';
import 'package:flutter_picker_plus/picker.dart';
import 'package:one_key/provider/customer_provider.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/dialog_util.dart';
import 'package:one_key/utils/screen_util.dart';
import 'package:one_key/utils/utils.dart';
import 'package:one_key/widgets/MyDivider.dart';
import 'package:one_key/widgets/h_empty_view.dart';
import 'package:one_key/widgets/system_app_bar.dart';
import 'package:one_key/widgets/v_empty_view.dart';
import 'package:provider/provider.dart';
import 'package:flutter_lunar_datetime_picker/flutter_lunar_datetime_picker.dart';
import 'package:flutter_lunar_datetime_picker/datetime_picker_theme.dart'
as picker_theme;
/**
* 客户生日编辑页面
*/
class SetBirthdayPage extends StatefulWidget {
final String? gid;
const SetBirthdayPage({super.key, required this.gid});
@override
State<SetBirthdayPage> createState() => _SetBirthdayPageState();
}
class _SetBirthdayPageState extends State<SetBirthdayPage> {
late CustomerProvider customerProvider;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
String birthday = '';
_item(
String title,
String subTitle, {
GestureTapCallback? onTapDel,
GestureTapCallback? onTapEdit,
}) {
return Container(
padding: EdgeInsets.all(w(10)),
margin: EdgeInsets.symmetric(horizontal: w(20)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'${title}生日',
style: TextStyle(
fontSize: font(16), color: MyColours.color_438E93),
),
Spacer(),
InkWell(
onTap: onTapDel,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: w(10)),
child: Image.asset(
Utils.getImgPath('f_delete_red'),
width: w(20),
),
)),
InkWell(
onTap: onTapEdit,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: w(10)),
child: Image.asset(
Utils.getImgPath('c_edit'),
width: w(20),
),
)),
],
),
VEmptyView(40),
Text(
'(${title})${subTitle}',
style: TextStyle(fontSize: font(16), color: MyColours.color_000000),
),
VEmptyView(20),
Padding(
padding: EdgeInsets.symmetric(horizontal: w(10)),
child: MyDivider(
double.infinity,
w(1),
color: MyColours.color_F7F7F7,
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
customerProvider = Provider.of<CustomerProvider>(context, listen: true);
return Scaffold(
appBar: SystemAppBar('客户生日'),
key: scaffoldKey,
backgroundColor: MyColours.color_ffffff,
body: SingleChildScrollView(
child: Column(
children: [
VEmptyView(40),
_item('公历', '1993年1月3日', onTapDel: () {}, onTapEdit: () {
DatePicker.showDatePicker(
context,
lunarPicker: false,
showTime: false,
theme: picker_theme.DatePickerTheme(
backgroundColor: MyColours.color_ffffff,
itemStyle: TextStyle(
color: MyColours.color_438E93, fontSize: font(16)),
containerHeight: w(220),
titleHeight: w(58),
itemHeight: w(44),
cancelStyle: TextStyle(
color: MyColours.color_999999, fontSize: font(16)),
doneStyle: TextStyle(
color: MyColours.color_438E93, fontSize: font(16))),
dateInitTime: DateInitTime(
currentTime: DateTime.now(),
maxTime: DateTime(2050, 12, 12),
minTime: DateTime(1900, 1, 1)),
onConfirm: (time, lunar) {
debugPrint(time.toString());
},
onChanged: (time, lunar) {
debugPrint("change:${time.toString()}");
},
);
// DialogUtil.showPickerDateTime24(
// context,
// scaffoldKey,
// (value) async {
// // {'text': picker.adapter.text, 'select': selecteds}
// if (value != null) {
// setState(() {
// print(value);
// birthday = DateUtil.formatDateStr(value,
// format: DateFormats.y_mo_d);
// });
// // 请求接口,设置生日
// String from = birthday + ' 00:00:00';
// Map<String, String?> params = {
// 'id': widget.gid,
// 'c_day':
// '${(DateUtil.getDateMsByTimeStr(from)! / 1000).floor()}',
// };
// bool sucess = await customerProvider
// .setGuestInfo(context, params, showLoading: true);
// if (sucess) {
// Utils.showToast('保存成功');
// }
// }
// // showDateSelWidget = false;
// },
// yearBegin: 1925,
// minValue: DateTime(1925),
// dateTime: birthday == ''
// ? DateTime.now()
// : DateUtil.getDateTime(birthday),
// pickerDateTimeType: PickerDateTimeType.kYMD,
// onCancel: () {
// // showDateSelWidget = false;
// });
}),
VEmptyView(40),
_item('农历', '1969年三月廿五', onTapDel: () {}, onTapEdit: () {
DatePicker.showDatePicker(
context,
lunarPicker: true,
showTime: false,
theme: picker_theme.DatePickerTheme(
backgroundColor: MyColours.color_ffffff,
itemStyle: TextStyle(
color: MyColours.color_438E93, fontSize: font(16)),
containerHeight: w(220),
titleHeight: w(58),
itemHeight: w(44),
cancelStyle: TextStyle(
color: MyColours.color_999999, fontSize: font(16)),
doneStyle: TextStyle(
color: MyColours.color_438E93, fontSize: font(16))),
dateInitTime: DateInitTime(
currentTime: DateTime.now(),
maxTime: DateTime(2050, 12, 12),
minTime: DateTime(1900, 1, 1)),
onConfirm: (time, lunar) {
debugPrint(time.toString());
},
onChanged: (time, lunar) {
debugPrint("change:${time.toString()}");
},
);
}),
],
),
));
}
}
... ...
import 'package:flutter/material.dart';
class MyColours {
static const Color color_EFEFF0 = Color(0xFFEFEFF0);
static const Color color_FFEFC5 = Color(0xFFFFEFC5);
static const Color color_E4461D = Color(0xFFE4461D);
static const Color color_F8F7F3 = Color(0xFFF8F7F3);
... ...
... ... @@ -2451,4 +2451,27 @@ class NavigatorUtil {
return _navigateTo(context, "${Routes.enterprise_information_upload_page}",
replace: replace);
}
///客户生日
static Future<dynamic> goSetBirthdayPage(
BuildContext context,String? gid, {
replace = false,
}) {
return _navigateTo(context, "${Routes.set_birthday_page}?gid=$gid",
replace: replace);
}
}
... ...
... ... @@ -70,6 +70,7 @@ import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_
import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_detail_page_seller.dart';
import 'package:one_key/pages/my/customer_type/my_customer/my_marketing_records_page.dart';
import 'package:one_key/pages/my/customer_type/my_customer/my_show_customer_list_page.dart';
import 'package:one_key/pages/my/customer_type/store_customer/set_birthday_page.dart';
import 'package:one_key/pages/my/customer_type/store_customer/show_customer_list_page.dart';
import 'package:one_key/pages/my/customer_type/store_customer/customer_detail_edit_page.dart';
... ... @@ -2077,13 +2078,14 @@ var couponToPersonnelPageHandle = new Handler(
bool onlyShow =
FluroConvertUtils.string2bool(params["onlyShow"]!.first as String);
String id = params["id"]!.first as String;
String id = params["id"]!.first as String;
bool needSave = FluroConvertUtils.string2bool(params["needSave"]!.first as String);
bool needSave =
FluroConvertUtils.string2bool(params["needSave"]!.first as String);
return ChangeNotifierProvider<PersonnelProvider>(
create: (_) => PersonnelProvider(),
child: CouponToPersonnalPage(uids: uids, onlyShow: onlyShow,needSave:needSave,id:id));
child: CouponToPersonnalPage(
uids: uids, onlyShow: onlyShow, needSave: needSave, id: id));
});
///宴会----宴会看板
... ... @@ -4223,8 +4225,6 @@ var transactionRecordDetailPageHandle = new Handler(
child: TransactionRecordDetailPage(status: status, id: id));
});
var depositRecordDetailPageHandle = new Handler(
handlerFunc: (BuildContext? context, Map<String, List<Object>> params) {
String id = params["id"]!.first as String;
... ... @@ -4239,11 +4239,9 @@ var depositRecordDetailPageHandle = new Handler(
// }
return ChangeNotifierProvider<FinanceProvider>(
create: (_) => FinanceProvider(),
child: DepositRecordDetailPage( id: id));
create: (_) => FinanceProvider(), child: DepositRecordDetailPage(id: id));
});
var vipRecordDetailPageHandle = new Handler(
handlerFunc: (BuildContext? context, Map<String, List<Object>> params) {
String id = params["id"]!.first as String;
... ... @@ -4258,15 +4256,25 @@ var vipRecordDetailPageHandle = new Handler(
// }
return ChangeNotifierProvider<FinanceProvider>(
create: (_) => FinanceProvider(),
child:VipRecordDetailPage(id: id));
create: (_) => FinanceProvider(), child: VipRecordDetailPage(id: id));
});
var setBirthdayPageHandle = new Handler(
handlerFunc: (BuildContext? context, Map<String, List<Object>> params) {
String? gid = params["gid"]!.first as String;
// String status = params["status"]!.first as String;
// bool isMine =
// FluroConvertUtils.string2bool(params["isMine"]!.first as String);
// CouponSunModel? couponSunModel;
// if (params.keys.contains("couponSunModel")) {
// couponSunModel = CouponSunModel.fromJson(json.decode(
// FluroConvertUtils.fluroCnParamsDecode(
// params["couponSunModel"]!.first as String)));
// }
return ChangeNotifierProvider<CustomerProvider>(
create: (_) => CustomerProvider(), child: SetBirthdayPage(gid:gid));
});
///支付返券
var paymentGiftPageHandle = new Handler(
... ...
... ... @@ -415,28 +415,19 @@ class Routes {
static String transaction_record_detail_page =
"/transaction_record_detail_page"; //订单消费详情
static String payment_gift_page =
"/payment_gift_page"; //支付返券
static String payment_gift_select_page =
static String payment_gift_page = "/payment_gift_page"; //支付返券
static String payment_gift_select_page =
"/payment_gift_select_page"; //支付返券选择券页面(免费代金券)
static String enterprise_information_upload_page =
static String enterprise_information_upload_page =
"/enterprise_information_upload_page"; //企业客户资料上传页面
static String deposit_record_detail_page =
static String deposit_record_detail_page =
"/deposit_record_detail_page"; //预订订金详情页
static String vip_record_detail_page=
"/vip_record_detail_page"; //会员充值订单详情页
static String vip_record_detail_page = "/vip_record_detail_page"; //会员充值订单详情页
static String set_birthday_page = "/set_birthday_page"; //客户生日
static void configureRoutes(FluroRouter router) {
router.notFoundHandler = new Handler(
... ... @@ -803,37 +794,24 @@ class Routes {
router.define(transaction_record_home_page,
handler: transactionRecordHomePageHandle);
router.define(transaction_record_search_page,
handler: transactionRecordSearchPageHandle);
router.define(transaction_record_detail_page,
router.define(transaction_record_search_page,
handler: transactionRecordSearchPageHandle);
router.define(transaction_record_detail_page,
handler: transactionRecordDetailPageHandle);
router.define(payment_gift_page,
handler: paymentGiftPageHandle);
router.define(payment_gift_select_page,
handler:paymentGiftSelectPageHandle);
router.define(enterprise_information_upload_page,
handler:enterpriseInformationUploadPageHandle);
router.define(deposit_record_detail_page,
handler:depositRecordDetailPageHandle);
router.define(vip_record_detail_page,
handler:vipRecordDetailPageHandle);
router.define(payment_gift_page, handler: paymentGiftPageHandle);
router.define(payment_gift_select_page,
handler: paymentGiftSelectPageHandle);
router.define(enterprise_information_upload_page,
handler: enterpriseInformationUploadPageHandle);
router.define(deposit_record_detail_page,
handler: depositRecordDetailPageHandle);
router.define(vip_record_detail_page, handler: vipRecordDetailPageHandle);
router.define(set_birthday_page, handler: setBirthdayPageHandle);
}
}
... ...
... ... @@ -12057,7 +12057,7 @@ class DialogUtil {
onTap: () {
FocusScope.of(context).requestFocus(
FocusNode()); //点击空白处隐藏键盘
incrementCounterYear(
incrementCounterYear(
context,
gongli,
yearStr == '选填'
... ...
## 1.0.1
* Flutter Solar + lunar time selector
## 1.0.2
* [fix] Lunar callback.
## 1.0.3
* [add] show time check.
## 1.0.4
* [fix] The lunar leap month caused the switch from the Gregorian calendar to the Gregorian calendar, incorrect.
## 1.0.5
* [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.
* [add] Suitable for Flutter 3.x version.
## 1.0.6
* [add] Lunar type show lunar year.
\ No newline at end of file
... ...
MIT License
Copyright (c) 2022 周枇杷!
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
... ...
## Flutter 农历日期选择器
| 阳历显示 | 阴历显示 |
| -------------------- | -------------------------------- |
| ![](screen_date_time.png) | ![](screen_lunar_date_time.png) | ![](screen_datetime_chinese.png) |
## 引用
``` yaml
flutter_lunar_datetime_picker: ^last_version
```
## 使用
``` dart
DatePicker.showDatePicker(
context,
lunarPicker: false,
dateInitTime: DateInitTime(
currentTime: DateTime.now(),
maxTime: DateTime(2026, 12, 12),
minTime: DateTime(2018, 3, 4)),
onConfirm: (time) {
debugPrint(time.toString());
},
onChanged: (time) {
debugPrint("change:${time.toString()}");
},
);
```
## 感谢
- [flutter_datetime_picker](https://github.com/Realank/flutter_datetime_picker) 提供PickerView方案
- [lunar_flutter](https://github.com/6tail/lunar-flutter) 提供农历日期算法
\ No newline at end of file
... ...
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
... ...
# example
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
... ...
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
... ...
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.loquatz.example.example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.loquatz.example.example">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.loquatz.example.example">
<application
android:label="example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
... ...
package io.flutter.plugins;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterEngine;
/**
* Generated file. Do not edit.
* This file is generated by the Flutter tool based on the
* plugins that support the Android platform.
*/
@Keep
public final class GeneratedPluginRegistrant {
private static final String TAG = "GeneratedPluginRegistrant";
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
}
}
... ...
package com.loquatz.example.example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
... ...
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.loquatz.example.example">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
... ...
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
... ...
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
... ...
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
... ...
sdk.dir=/Users/wangdongni/Library/Android/sdk
flutter.sdk=/Users/wangdongni/fvm/versions/3.27.3
\ No newline at end of file
... ...
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
... ...
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/Users/wangdongni/fvm/versions/3.27.3
FLUTTER_APPLICATION_PATH=/Users/wangdongni/Desktop/Flutter-ReserveApp/library/flutter_lunar_datetime_picker-1.0.6/example
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=lib/main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=1.0.0
FLUTTER_BUILD_NUMBER=1
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=.dart_tool/package_config.json
... ...
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/wangdongni/fvm/versions/3.27.3"
export "FLUTTER_APPLICATION_PATH=/Users/wangdongni/Desktop/Flutter-ReserveApp/library/flutter_lunar_datetime_picker-1.0.6/example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
... ...
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.loquatz.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.loquatz.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.loquatz.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
... ...
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
... ...
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
... ...
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
... ...
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
... ...
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
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.
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
... ...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
... ...
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GeneratedPluginRegistrant_h
#define GeneratedPluginRegistrant_h
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface GeneratedPluginRegistrant : NSObject
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
@end
NS_ASSUME_NONNULL_END
#endif /* GeneratedPluginRegistrant_h */
... ...
//
// Generated file. Do not edit.
//
// clang-format off
#import "GeneratedPluginRegistrant.h"
@implementation GeneratedPluginRegistrant
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
}
@end
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Example</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
... ...
import 'package:flutter/material.dart';
import 'package:flutter_lunar_datetime_picker/date_init.dart';
import 'package:flutter_lunar_datetime_picker/flutter_lunar_datetime_picker.dart';
import 'package:intl/intl.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
/// 日期
String? time = '1995-11-8 12:12';
/// 是否是农历
bool lunar = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("日期选择器"),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"日期:$time",
style: const TextStyle(fontSize: 30),
),
const SizedBox(height: 100),
ElevatedButton(
onPressed: () {
DatePicker.showDatePicker(
context,
lunarPicker: lunar,
showTime: true,
showLunarYear: true,
dateInitTime: time == null
? DateInitTime(
currentTime: DateTime.now(),
maxTime: DateTime(2026, 12, 12),
minTime: DateTime(1995, 2, 4))
: DateInitTime(
currentTime:
DateFormat("yyyy-MM-dd h:m").parse(time ?? ""),
maxTime: DateTime(2026, 12, 12),
minTime: DateTime(1995, 2, 4)),
onConfirm: (time, lunar) {
debugPrint(time.toString());
setState(() {
this.time =
"${time.year}-${time.month}-${time.day} ${time.hour}:${time.minute}";
this.lunar = lunar;
});
},
onChanged: (time, lunar) {
debugPrint("change:${time.toString()}");
},
);
},
child: const Text("选择"),
)
],
)),
);
}
}
... ...
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.19.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.8"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.3"
flutter_lunar_datetime_picker:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "1.0.6"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
intl:
dependency: "direct main"
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.17.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
url: "https://pub.flutter-io.cn"
source: hosted
version: "10.0.7"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.8"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
lunar:
dependency: "direct main"
description:
name: lunar
sha256: "4ebb40c1647c5903fc67ff0be09a4ce90da79b482f0c78a8c727086a67375c37"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.7.5"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.15.0"
path:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.9.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.12.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.7.3"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
url: "https://pub.flutter-io.cn"
source: hosted
version: "14.3.0"
sdks:
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"
... ...
name: example
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: '>=2.18.1 <3.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
flutter_lunar_datetime_picker:
path: ../
lunar: ^1.2.21
intl: ^0.17.0
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
... ...
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:example/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}
... ...
/// Outputs year as four digits
///
/// Example:
/// formatDate(new DateTime(2018,8,31), [yMDW]);
/// // => Today
const String yMDW = 'ymdw';
///
/// Example:
/// formatDate(new DateTime(1989), [yyyy]);
/// // => 1989
const String yyyy = 'yyyy';
/// Outputs year as two digits
///
/// Example:
/// formatDate(new DateTime(1989), [yy]);
/// // => 89
const String yy = 'yy';
/// Outputs month as two digits
///
/// Example:
/// formatDate(new DateTime(1989, 11), [mm]);
/// // => 11
/// formatDate(new DateTime(1989, 5), [mm]);
/// // => 05
const String mm = 'mm';
/// Outputs month compactly
///
/// Example:
/// formatDate(new DateTime(1989, 11), [mm]);
/// // => 11
/// formatDate(new DateTime(1989, 5), [m]);
/// // => 5
const String m = 'm';
/// Outputs month as long name
///
/// Example:
/// formatDate(new DateTime(1989, 2), [mM]);
/// // => february
const String mM = 'MM';
/// Outputs month as short name
///
/// Example:
/// formatDate(new DateTime(1989, 2), [M]);
/// // => feb
const String M = 'M';
/// Outputs day as two digits
///
/// Example:
/// formatDate(new DateTime(1989, 2, 21), [dd]);
/// // => 21
/// formatDate(new DateTime(1989, 2, 5), [dd]);
/// // => 05
const String dd = 'dd';
/// Outputs day compactly
///
/// Example:
/// formatDate(new DateTime(1989, 2, 21), [d]);
/// // => 21
/// formatDate(new DateTime(1989, 2, 5), [d]);
/// // => 5
const String d = 'd';
/// Outputs week in month
///
/// Example:
/// formatDate(new DateTime(1989, 2, 21), [w]);
/// // => 4
const String w = 'w';
/// Outputs week in year as two digits
///
/// Example:
/// formatDate(new DateTime(1989, 12, 31), [W]);
/// // => 53
/// formatDate(new DateTime(1989, 2, 21), [W]);
/// // => 08
const String wW = 'WW';
/// Outputs week in year compactly
///
/// Example:
/// formatDate(new DateTime(1989, 2, 21), [W]);
/// // => 8
const String W = 'W';
/// Outputs week day as long name
///
/// Example:
/// formatDate(new DateTime(2018, 1, 14), [D]);
/// // => sun
const String D = 'D';
/// Outputs hour (0 - 11) as two digits
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15), [hh]);
/// // => 03
const String hh = 'hh';
/// Outputs hour (0 - 11) compactly
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15), [h]);
/// // => 3
const String h = 'h';
/// Outputs hour (0 to 23) as two digits
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15), [hH]);
/// // => 15
const String hH = 'HH';
/// Outputs hour (0 to 23) compactly
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 5), [H]);
/// // => 5
const String H = 'H';
/// Outputs minute as two digits
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15, 40), [nn]);
/// // => 40
/// formatDate(new DateTime(1989, 02, 1, 15, 4), [nn]);
/// // => 04
const String nn = 'nn';
/// Outputs minute compactly
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15, 4), [n]);
/// // => 4
const String n = 'n';
/// Outputs second as two digits
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10), [ss]);
/// // => 10
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 5), [ss]);
/// // => 05
const String ss = 'ss';
/// Outputs second compactly
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 5), [s]);
/// // => 5
const String s = 's';
/// Outputs millisecond as three digits
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 999), [sSS]);
/// // => 999
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 99), [SS]);
/// // => 099
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0), [SS]);
/// // => 009
const String sSS = 'SSS';
/// Outputs millisecond compactly
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 999), [sSS]);
/// // => 999
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 99), [SS]);
/// // => 99
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 9), [SS]);
/// // => 9
const String S = 'S';
/// Outputs microsecond as three digits
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 999), [uuu]);
/// // => 999
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 99), [uuu]);
/// // => 099
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 9), [uuu]);
/// // => 009
const String uuu = 'uuu';
/// Outputs millisecond compactly
///
/// Example:
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 999), [u]);
/// // => 999
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 99), [u]);
/// // => 99
/// formatDate(new DateTime(1989, 02, 1, 15, 40, 10, 0, 9), [u]);
/// // => 9
const String u = 'u';
/// Outputs if hour is AM or PM
///
/// Example:
/// print(formatDate(new DateTime(1989, 02, 1, 5), [am]));
/// // => AM
/// print(formatDate(new DateTime(1989, 02, 1, 15), [am]));
/// // => PM
const String am = 'am';
/// Outputs timezone as time offset
///
/// Example:
///
const String z = 'z';
const String Z = 'Z';
String digits(int value, int length) {
return '$value'.padLeft(length, "0");
}
int dayInYear(DateTime date) =>
date.difference(DateTime(date.year, 1, 1)).inDays;
... ...
class DateInitTime {
DateInitTime({
this.currentTime,
this.maxTime,
this.minTime,
});
DateTime? currentTime;
DateTime? maxTime;
DateTime? minTime;
}
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter_lunar_datetime_picker/date_format.dart';
import 'package:flutter_lunar_datetime_picker/datetime_util.dart';
import 'package:lunar/lunar.dart';
//interface for picker data model
abstract class BasePickerModel {
//a getter method for left column data, return null to end list
String? leftStringAtIndex(int index);
//a getter method for middle column data, return null to end list
String? middleStringAtIndex(int index);
//a getter method for right column data, return null to end list
String? rightStringAtIndex(int index);
String? hourStringAtIndex(int index);
String? minuteStringAtIndex(int index);
//set selected left index
void setLeftIndex(int index);
//set selected middle index
void setMiddleIndex(int index);
//set selected right index
void setRightIndex(int index);
void setHourIndex(int index);
void setMinuteIndex(int index);
//return current left index
int currentLeftIndex();
//return current middle index
int currentMiddleIndex();
//return current right index
int currentRightIndex();
int currentHourIndex();
int currentMinuteIndex();
//return final time
DateTime? finalTime();
//return left divider string
String leftDivider();
//return right divider string
String rightDivider();
String timeDivider();
//layout proportions for 3 columns
List<int> layoutProportions();
}
//a base class for picker data model
class CommonPickerModel extends BasePickerModel {
late List<String> leftList;
late List<String> middleList;
late List<String> rightList;
late List<String> hourList;
late List<String> minuteList;
late DateTime currentTime;
late int _currentLeftIndex;
late int _currentMiddleIndex;
late int _currentRightIndex;
late int _currentHourIndex;
late int _currentMinuteIndex;
CommonPickerModel();
@override
String? leftStringAtIndex(int index) {
return null;
}
@override
String? middleStringAtIndex(int index) {
return null;
}
@override
String? rightStringAtIndex(int index) {
return null;
}
@override
int currentLeftIndex() {
return _currentLeftIndex;
}
@override
int currentMiddleIndex() {
return _currentMiddleIndex;
}
@override
int currentRightIndex() {
return _currentRightIndex;
}
@override
void setLeftIndex(int index) {
_currentLeftIndex = index;
}
@override
void setMiddleIndex(int index) {
_currentMiddleIndex = index;
}
@override
void setRightIndex(int index) {
_currentRightIndex = index;
}
@override
String leftDivider() {
return "";
}
@override
String rightDivider() {
return "";
}
@override
List<int> layoutProportions() {
return [3, 3, 3, 2, 2];
}
@override
DateTime? finalTime() {
return null;
}
@override
int currentHourIndex() {
return _currentHourIndex;
}
@override
int currentMinuteIndex() {
return _currentMinuteIndex;
}
@override
String? hourStringAtIndex(int index) {
return null;
}
@override
String? minuteStringAtIndex(int index) {
return null;
}
@override
void setHourIndex(int index) {
_currentHourIndex = index;
}
@override
void setMinuteIndex(int index) {
_currentMinuteIndex = index;
}
@override
String timeDivider() {
return ":";
}
}
//a date picker model
class DatePickerModel extends CommonPickerModel {
late DateTime maxTime;
late DateTime minTime;
DatePickerModel({
DateTime? currentTime,
DateTime? maxTime,
DateTime? minTime,
}) {
this.maxTime = maxTime ?? DateTime(2049, 12, 31);
this.minTime = minTime ?? DateTime(1970, 1, 1);
currentTime = currentTime ?? DateTime.now();
if (currentTime.compareTo(this.maxTime) > 0) {
currentTime = this.maxTime;
} else if (currentTime.compareTo(this.minTime) < 0) {
currentTime = this.minTime;
}
this.currentTime = currentTime;
_fillLeftLists();
_fillMiddleLists();
_fillRightLists();
int minMonth = _minMonthOfCurrentYear();
int minDay = _minDayOfCurrentMonth();
_currentLeftIndex = this.currentTime.year - this.minTime.year;
_currentMiddleIndex = this.currentTime.month - minMonth;
_currentRightIndex = this.currentTime.day - minDay;
_currentHourIndex = this.currentTime.hour;
_currentMinuteIndex = this.currentTime.minute;
}
void _fillLeftLists() {
leftList = List.generate(maxTime.year - minTime.year + 1, (int index) {
// print('LEFT LIST... ${minTime.year + index}${_localeYear()}');
return '${minTime.year + index}年';
});
}
int _maxMonthOfCurrentYear() {
return currentTime.year == maxTime.year ? maxTime.month : 12;
}
int _minMonthOfCurrentYear() {
return currentTime.year == minTime.year ? minTime.month : 1;
}
int _maxDayOfCurrentMonth() {
int dayCount = calcDateCount(currentTime.year, currentTime.month);
return currentTime.year == maxTime.year &&
currentTime.month == maxTime.month
? maxTime.day
: dayCount;
}
int _minDayOfCurrentMonth() {
return currentTime.year == minTime.year &&
currentTime.month == minTime.month
? minTime.day
: 1;
}
void _fillMiddleLists() {
int minMonth = _minMonthOfCurrentYear();
int maxMonth = _maxMonthOfCurrentYear();
middleList = List.generate(maxMonth - minMonth + 1, (int index) {
return '${minMonth + index}月';
});
}
void _fillRightLists() {
int maxDay = _maxDayOfCurrentMonth();
int minDay = _minDayOfCurrentMonth();
rightList = List.generate(maxDay - minDay + 1, (int index) {
return '${minDay + index}日';
});
}
@override
void setLeftIndex(int index) {
super.setLeftIndex(index);
//adjust middle
int destYear = index + minTime.year;
int minMonth = _minMonthOfCurrentYear();
DateTime newTime;
//change date time
if (currentTime.month == 2 && currentTime.day == 29) {
newTime = currentTime.isUtc
? DateTime.utc(
destYear,
currentTime.month,
calcDateCount(destYear, 2),
)
: DateTime(
destYear,
currentTime.month,
calcDateCount(destYear, 2),
);
} else {
newTime = currentTime.isUtc
? DateTime.utc(
destYear,
currentTime.month,
currentTime.day,
)
: DateTime(
destYear,
currentTime.month,
currentTime.day,
);
}
//min/max check
if (newTime.isAfter(maxTime)) {
currentTime = maxTime;
} else if (newTime.isBefore(minTime)) {
currentTime = minTime;
} else {
currentTime = newTime;
}
_fillMiddleLists();
_fillRightLists();
minMonth = _minMonthOfCurrentYear();
int minDay = _minDayOfCurrentMonth();
_currentMiddleIndex = currentTime.month - minMonth;
_currentRightIndex = currentTime.day - minDay;
}
@override
void setMiddleIndex(int index) {
super.setMiddleIndex(index);
//adjust right
int minMonth = _minMonthOfCurrentYear();
int destMonth = minMonth + index;
DateTime newTime;
//change date time
int dayCount = calcDateCount(currentTime.year, destMonth);
newTime = currentTime.isUtc
? DateTime.utc(
currentTime.year,
destMonth,
currentTime.day <= dayCount ? currentTime.day : dayCount,
)
: DateTime(
currentTime.year,
destMonth,
currentTime.day <= dayCount ? currentTime.day : dayCount,
);
//min/max check
if (newTime.isAfter(maxTime)) {
currentTime = maxTime;
} else if (newTime.isBefore(minTime)) {
currentTime = minTime;
} else {
currentTime = newTime;
}
_fillRightLists();
int minDay = _minDayOfCurrentMonth();
_currentRightIndex = currentTime.day - minDay;
}
@override
void setRightIndex(int index) {
super.setRightIndex(index);
int minDay = _minDayOfCurrentMonth();
currentTime = currentTime.isUtc
? DateTime.utc(
currentTime.year,
currentTime.month,
minDay + index,
)
: DateTime(
currentTime.year,
currentTime.month,
minDay + index,
);
}
@override
String? leftStringAtIndex(int index) {
if (index >= 0 && index < leftList.length) {
return leftList[index];
} else {
return null;
}
}
@override
String? middleStringAtIndex(int index) {
if (index >= 0 && index < middleList.length) {
return middleList[index];
} else {
return null;
}
}
@override
String? rightStringAtIndex(int index) {
if (index >= 0 && index < rightList.length) {
return rightList[index];
} else {
return null;
}
}
@override
String? hourStringAtIndex(int index) {
if (index >= 0 && index < 24) {
return digits(index, 2);
} else {
return null;
}
}
@override
String? minuteStringAtIndex(int index) {
if (index >= 0 && index < 60) {
return digits(index, 2);
} else {
return null;
}
}
@override
DateTime finalTime() {
return currentTime.isUtc
? DateTime.utc(currentTime.year, currentTime.month, currentTime.day,
_currentHourIndex, _currentMinuteIndex)
: DateTime(currentTime.year, currentTime.month, currentTime.day,
_currentHourIndex, _currentMinuteIndex);
}
}
class LunarPickerModel extends CommonPickerModel {
late DateTime maxTime;
late DateTime minTime;
late Lunar maxLunarTime;
late Lunar minLunarTime;
late Lunar currentLunarTime;
late bool showLunarYear;
LunarPickerModel(
{DateTime? currentTime, DateTime? maxTime, DateTime? minTime,bool? showLunarYear = false}) {
this.maxTime = maxTime ?? DateTime(2049, 12, 31);
this.minTime = minTime ?? DateTime(1970, 1, 1);
this.showLunarYear = showLunarYear ?? false;
currentTime = currentTime ?? DateTime.now();
// 阳历转阴历
maxLunarTime = Solar.fromDate(this.maxTime).getLunar();
minLunarTime = Solar.fromDate(this.minTime).getLunar();
// 获取当前阴历
currentLunarTime = Solar.fromDate(currentTime).getLunar();
debugPrint("currentLunarTime:$currentLunarTime");
if (currentTime.compareTo(this.maxTime) > 0) {
currentTime = this.maxTime;
currentLunarTime = maxLunarTime;
} else if (currentTime.compareTo(this.minTime) < 0) {
currentTime = this.minTime;
currentLunarTime = minLunarTime;
}
this.currentTime = currentTime;
_fillLeftLists();
_fillMiddleLists();
_fillRightLists();
int minDay = _minDayOfCurrentMonth();
_currentLeftIndex = currentLunarTime.getYear() - minLunarTime.getYear();
_currentMiddleIndex = _getCurrentMiddleIndex();
_currentRightIndex = currentLunarTime.getDay() - minDay;
_currentHourIndex = this.currentTime.hour;
_currentMinuteIndex = this.currentTime.minute;
}
/// 当前年的最大月份
int _maxMonthOfCurrentYear() {
return currentLunarTime.getYear() == maxLunarTime.getYear()
? maxLunarTime.getMonth()
: 12;
}
/// 当前年的最小月份
int _minMonthOfCurrentYear() {
return currentLunarTime.getYear() == minLunarTime.getYear()
? minLunarTime.getMonth()
: 1;
}
/// 当月的最大天数
int _maxDayOfCurrentMonth() {
// 当月天数
int dayCount = LunarMonth.fromYm(
currentLunarTime.getYear(), currentLunarTime.getMonth())
?.getDayCount() ??
0;
return currentLunarTime.getYear() == maxLunarTime.getYear() &&
currentLunarTime.getMonth() == maxLunarTime.getMonth()
? maxLunarTime.getDay()
: dayCount;
}
/// 当月的最小天数
int _minDayOfCurrentMonth() {
return currentLunarTime.getYear() == minLunarTime.getYear() &&
currentLunarTime.getMonth() == minLunarTime.getMonth()
? minLunarTime.getDay()
: 1;
}
void _fillLeftLists() {
leftList = List.generate(
maxLunarTime.getYear() - minLunarTime.getYear() + 1, (int index) {
// print('LEFT LIST... ${minTime.year + index}${_localeYear()}');
if (showLunarYear) {
return '${getYearInChinese(minLunarTime.getYear()+index)}年';
} else {
return '${minLunarTime.getYear() + index}年';
}
});
}
String getYearInChinese(int year) {
String y = year.toString();
String s = '';
for (int i = 0, j = y.length; i < j; i++) {
s += LunarUtil.NUMBER[y.codeUnitAt(i) - 48];
}
return s;
}
void _fillMiddleLists() {
int minMonth = _minMonthOfCurrentYear();
int maxMonth = _maxMonthOfCurrentYear();
var lunarMonths =
LunarYear.fromYear(currentLunarTime.getYear()).getMonths();
middleList = [];
// print("--${lunarMonths.length}");
// 因为农历月份中有闰月所以需要遍历当前所有月份进行查找
for (var i = 0, j = lunarMonths.length; i < j; i++) {
// print(lunarMonths[i].toString());
if (lunarMonths[i].getYear() == currentLunarTime.getYear()) {
if (currentLunarTime.getYear() == minLunarTime.getYear()) {
if (i >= minMonth + 1) {
getLunarMiddleMonth(lunarMonths[i]);
}
} else if (currentLunarTime.getYear() == maxLunarTime.getYear()) {
if (i <= maxMonth + 1) {
getLunarMiddleMonth(lunarMonths[i]);
}
} else {
getLunarMiddleMonth(lunarMonths[i]);
}
}
}
// print(this.middleList.length);
}
/// 检查是否是闰月
bool isLeap(LunarMonth m) => m.getMonth() < 0;
/// 格式化获取农历月
getLunarMiddleMonth(LunarMonth m) {
String month = LunarUtil.MONTH[m.getMonth().abs()];
middleList.add("${isLeap(m) ? "闰" : ""}$month月");
}
void _fillRightLists() {
int maxDay = _maxDayOfCurrentMonth();
int minDay = _minDayOfCurrentMonth();
// print("${currentLunarTime.toString()}-${_maxDayOfCurrentMonth()}");
rightList = List.generate(
maxDay - minDay + 1 < _maxDayOfCurrentMonth()
? maxDay - minDay + 1
: _maxDayOfCurrentMonth(), (int index) {
return LunarUtil.DAY[minDay + index];
});
}
@override
void setLeftIndex(int index) {
super.setLeftIndex(index);
//adjust middle
int destYear = index + minLunarTime.getYear();
DateTime newTime;
// 当月天数
int dayCount =
LunarMonth.fromYm(destYear, currentTime.month)?.getDayCount() ?? 0;
// 当前日期不能大于当月最大天数 & d当前月可能无闰月
Lunar newLunarTime = Lunar.fromYmd(
destYear,
currentLunarTime.getMonth().abs(),
currentLunarTime.getDay() < dayCount
? currentLunarTime.getDay()
: dayCount);
// 阴历转阳历
var solarTime = newLunarTime.getSolar();
newTime =
DateTime(solarTime.getYear(), solarTime.getMonth(), solarTime.getDay());
// 此处使用阳历进行时间对比,阴历没有
if (newTime.isAfter(maxTime)) {
currentTime = maxTime;
currentLunarTime = maxLunarTime;
} else if (newTime.isBefore(minTime)) {
currentTime = minTime;
currentLunarTime = minLunarTime;
} else {
currentTime = newTime;
currentLunarTime = newLunarTime;
}
// print(currentTime);
_fillMiddleLists();
_fillRightLists();
int minDay = _minDayOfCurrentMonth();
_currentMiddleIndex = _getCurrentMiddleIndex();
_currentRightIndex = currentLunarTime.getDay() - minDay;
}
//获取当前最小月份指针
int _getCurrentMiddleIndex() {
int mCurrentMiddleIndex = 0;
/// 检查是否闰月
var leapMonth =
LunarYear.fromYear(currentLunarTime.getYear()).getLeapMonth();
debugPrint("isLeap:$isLeap");
debugPrint("当前年最小月份${_minMonthOfCurrentYear()}");
debugPrint("当前月份${currentLunarTime.getMonth()}");
// 查询当前月是否存在闰月
if (leapMonth != 0) {
// 当前存在闰月
if (currentLunarTime.getMonth() < 0) {
// 当前月份为闰月
mCurrentMiddleIndex =
currentLunarTime.getMonth().abs() - _minMonthOfCurrentYear() + 1;
} else {
if (currentLunarTime.getMonth() > leapMonth) {
// 如果当前月大于闰月
mCurrentMiddleIndex =
currentLunarTime.getMonth().abs() - _minMonthOfCurrentYear() + 1;
} else {
mCurrentMiddleIndex =
currentLunarTime.getMonth().abs() - _minMonthOfCurrentYear();
}
}
} else {
mCurrentMiddleIndex =
currentLunarTime.getMonth().abs() - _minMonthOfCurrentYear();
}
return mCurrentMiddleIndex;
}
@override
void setMiddleIndex(int index) {
super.setMiddleIndex(index);
//adjust right
int minMonth = _minMonthOfCurrentYear();
var d = LunarMonth.fromYm(currentLunarTime.getYear(), minMonth);
// 往后推x个月
LunarMonth? nextMonth = d?.next(index);
int dayCount = LunarMonth.fromYm(
currentLunarTime.getYear(), nextMonth?.getMonth() ?? 0)
?.getDayCount() ??
0;
Lunar newLunarTime = Lunar.fromYmd(
currentLunarTime.getYear(),
nextMonth?.getMonth() ?? 0,
currentLunarTime.getDay() <= dayCount
? currentLunarTime.getDay()
: dayCount);
DateTime newTime;
// 阴历转阳历
var solarTime = newLunarTime.getSolar();
newTime =
DateTime(solarTime.getYear(), solarTime.getMonth(), solarTime.getDay());
//min/max check
if (newTime.isAfter(maxTime)) {
currentTime = maxTime;
currentLunarTime = maxLunarTime;
} else if (newTime.isBefore(minTime)) {
currentTime = minTime;
currentLunarTime = minLunarTime;
} else {
currentTime = newTime;
currentLunarTime = newLunarTime;
}
_fillRightLists();
int minDay = _minDayOfCurrentMonth();
_currentRightIndex = currentLunarTime.getDay() - minDay;
}
@override
void setRightIndex(int index) {
super.setRightIndex(index);
int minDay = _minDayOfCurrentMonth();
int maxDay = _maxDayOfCurrentMonth();
///此处需要注意不能超过本月最大天数
Lunar newLunarTime = Lunar.fromYmd(
currentLunarTime.getYear(),
currentLunarTime.getMonth(),
(minDay + index <= maxDay) ? minDay + index : maxDay);
currentLunarTime = newLunarTime;
// 阴历转阳历
var solarTime = newLunarTime.getSolar();
currentTime =
DateTime(solarTime.getYear(), solarTime.getMonth(), solarTime.getDay());
}
@override
String? leftStringAtIndex(int index) {
if (index >= 0 && index < leftList.length) {
return leftList[index];
} else {
return null;
}
}
@override
String? middleStringAtIndex(int index) {
if (index >= 0 && index < middleList.length) {
return middleList[index];
} else {
return null;
}
}
@override
String? rightStringAtIndex(int index) {
if (index >= 0 && index < rightList.length) {
return rightList[index];
} else {
return null;
}
}
@override
String? hourStringAtIndex(int index) {
if (index >= 0 && index < 24) {
return digits(index, 2);
} else {
return null;
}
}
@override
String? minuteStringAtIndex(int index) {
if (index >= 0 && index < 60) {
return digits(index, 2);
} else {
return null;
}
}
@override
DateTime finalTime() {
return currentTime.isUtc
? DateTime.utc(currentTime.year, currentTime.month, currentTime.day,
_currentHourIndex, _currentMinuteIndex)
: DateTime(currentTime.year, currentTime.month, currentTime.day,
_currentHourIndex, _currentMinuteIndex);
}
@override
List<int> layoutProportions() {
return [4, 3, 3, 2, 2];
}
}
... ...
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class DatePickerTheme with DiagnosticableTreeMixin {
final TextStyle cancelStyle;
final TextStyle doneStyle;
final TextStyle itemStyle;
final Color backgroundColor;
final Color? headerColor;
final double containerHeight;
final double titleHeight;
final double itemHeight;
const DatePickerTheme({
this.cancelStyle = const TextStyle(color: Colors.black54, fontSize: 16),
this.doneStyle = const TextStyle(color: Colors.blue, fontSize: 16),
this.itemStyle = const TextStyle(color: Color(0xFF000046), fontSize: 18),
this.backgroundColor = Colors.white,
this.headerColor,
this.containerHeight = 210.0,
this.titleHeight = 44.0,
this.itemHeight = 36.0,
});
}
... ...
List<int> _leapYearMonths = const <int>[1, 3, 5, 7, 8, 10, 12];
int calcDateCount(int year, int month) {
if (_leapYearMonths.contains(month)) {
return 31;
} else if (month == 2) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
return 29;
}
return 28;
}
return 30;
}
... ...
library flutter_lunar_datetime_picker;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_lunar_datetime_picker/date_init.dart';
import 'package:flutter_lunar_datetime_picker/date_model.dart';
import 'package:flutter_lunar_datetime_picker/datetime_picker_theme.dart'
as picker_theme;
typedef DateChangedCallback = Function(DateTime time, bool lunar);
typedef DateCancelledCallback = Function();
typedef StringAtIndexCallBack = String? Function(int index);
class DatePicker {
///
/// Display date picker bottom sheet.
///
static Future<DateTime?> showDatePicker(
BuildContext context, {
bool showTitleActions = true,
DateTime? minTime,
DateTime? maxTime,
DateChangedCallback? onChanged,
DateChangedCallback? onConfirm,
DateCancelledCallback? onCancel,
DateTime? currentTime,
picker_theme.DatePickerTheme? theme,
bool? lunarPicker,
DateInitTime? dateInitTime,
bool? showTime,
bool? showLunarYear,
}) async {
return await Navigator.push(
context,
_DatePickerRoute(
showTitleActions: showTitleActions,
onChanged: onChanged,
onConfirm: onConfirm,
onCancel: onCancel,
theme: theme,
lunarPicker: lunarPicker,
dateInitTime: dateInitTime,
barrierLabel:
MaterialLocalizations.of(context).modalBarrierDismissLabel,
showTime: showTime,
showLunarYear: showLunarYear,
),
);
}
}
class _DatePickerRoute<T> extends PopupRoute<T> {
_DatePickerRoute({
this.showTitleActions,
this.onChanged,
this.onConfirm,
this.onCancel,
this.lunarPicker,
picker_theme.DatePickerTheme? theme,
this.dateInitTime,
this.barrierLabel,
this.showTime,
this.showLunarYear,
RouteSettings? settings,
}) : theme = theme ?? const picker_theme.DatePickerTheme(),
super(settings: settings);
final bool? showTitleActions;
final DateChangedCallback? onChanged;
final DateChangedCallback? onConfirm;
final DateCancelledCallback? onCancel;
final picker_theme.DatePickerTheme theme;
final bool? lunarPicker;
final DateInitTime? dateInitTime;
final bool? showTime;
final bool? showLunarYear;
@override
Duration get transitionDuration => const Duration(milliseconds: 200);
@override
bool get barrierDismissible => true;
@override
final String? barrierLabel;
@override
Color get barrierColor => Colors.black54;
AnimationController? _animationController;
@override
AnimationController createAnimationController() {
assert(_animationController == null);
_animationController =
BottomSheet.createAnimationController(navigator!.overlay!);
return _animationController!;
}
@override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
Widget bottomSheet = MediaQuery.removePadding(
context: context,
removeTop: true,
child: _DatePickerComponent(
onChanged: onChanged,
route: this,
lunarPicker: lunarPicker ?? false,
dateInitTime: dateInitTime,
showTime: showTime,
showLunarYear: showLunarYear ?? false,
),
);
return InheritedTheme.captureAll(context, bottomSheet);
}
}
class _DatePickerComponent extends StatefulWidget {
const _DatePickerComponent({
Key? key,
required this.route,
this.onChanged,
required this.lunarPicker,
required this.dateInitTime,
required this.showTime,
required this.showLunarYear,
}) : super(key: key);
final DateChangedCallback? onChanged;
final _DatePickerRoute route;
final bool lunarPicker;
final DateInitTime? dateInitTime;
final bool? showTime;
final bool? showLunarYear;
@override
State<StatefulWidget> createState() {
return _DatePickerState();
}
}
class _DatePickerState extends State<_DatePickerComponent> {
late FixedExtentScrollController leftScrollCtrl,
middleScrollCtrl,
rightScrollCtrl,
hourScrollCtrl,
minuteScrollCtrl;
bool lunarPicker = false;
late BasePickerModel pickerModel;
@override
void initState() {
super.initState();
// 是否阴历
lunarPicker = widget.lunarPicker;
if (lunarPicker) {
pickerModel = LunarPickerModel(
currentTime: widget.dateInitTime?.currentTime,
maxTime: widget.dateInitTime?.maxTime,
minTime: widget.dateInitTime?.minTime,
showLunarYear: widget.showLunarYear,
);
} else {
pickerModel = DatePickerModel(
currentTime: widget.dateInitTime?.currentTime,
maxTime: widget.dateInitTime?.maxTime,
minTime: widget.dateInitTime?.minTime);
}
refreshScrollOffset();
}
void onLunarChange(bool lunarPicker) {
setState(() {
this.lunarPicker = lunarPicker;
debugPrint("切换类型:${pickerModel.finalTime().toString()}");
pickerModel = lunarPicker
? LunarPickerModel(
currentTime: pickerModel.finalTime(),
maxTime: widget.dateInitTime?.maxTime,
minTime: widget.dateInitTime?.minTime,
showLunarYear: widget.showLunarYear)
: DatePickerModel(
currentTime: pickerModel.finalTime(),
maxTime: widget.dateInitTime?.maxTime,
minTime: widget.dateInitTime?.minTime);
});
refreshScrollOffset();
_notifyDateChanged();
}
void refreshScrollOffset() {
// debugPrint('refreshScrollOffset ${pickerModel.currentMiddleIndex()}');
leftScrollCtrl = FixedExtentScrollController(
initialItem: pickerModel.currentLeftIndex());
middleScrollCtrl = FixedExtentScrollController(
initialItem: pickerModel.currentMiddleIndex());
rightScrollCtrl = FixedExtentScrollController(
initialItem: pickerModel.currentRightIndex());
hourScrollCtrl = FixedExtentScrollController(
initialItem: pickerModel.currentHourIndex());
minuteScrollCtrl = FixedExtentScrollController(
initialItem: pickerModel.currentMinuteIndex());
}
@override
void dispose() {
leftScrollCtrl.dispose();
middleScrollCtrl.dispose();
rightScrollCtrl.dispose();
hourScrollCtrl.dispose();
minuteScrollCtrl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
picker_theme.DatePickerTheme theme = widget.route.theme;
return GestureDetector(
child: AnimatedBuilder(
animation: widget.route.animation!,
builder: (BuildContext context, Widget? child) {
final double bottomPadding = MediaQuery.of(context).padding.bottom;
return ClipRect(
child: CustomSingleChildLayout(
delegate: _BottomPickerLayout(
widget.route.animation!.value,
theme,
showTitleActions: widget.route.showTitleActions!,
bottomPadding: bottomPadding,
),
child: GestureDetector(
child: Material(
color: theme.backgroundColor,
child: _renderPickerView(theme),
),
),
),
);
},
),
);
}
void _notifyDateChanged() {
if (widget.onChanged != null) {
widget.onChanged!(pickerModel.finalTime()!, lunarPicker);
}
}
Widget _renderPickerView(picker_theme.DatePickerTheme theme) {
Widget itemView = _renderItemView(theme);
if (widget.route.showTitleActions == true) {
return Column(
children: <Widget>[
_renderTitleActionsView(theme),
itemView,
],
);
}
return itemView;
}
Widget _renderColumnView(
ValueKey key,
picker_theme.DatePickerTheme theme,
StringAtIndexCallBack stringAtIndexCB,
ScrollController scrollController,
int layoutProportion,
ValueChanged<int> selectedChangedWhenScrolling,
ValueChanged<int> selectedChangedWhenScrollEnd,
) {
return Expanded(
flex: layoutProportion,
child: Container(
// padding: const EdgeInsets.all(2.0),
height: theme.containerHeight,
decoration: BoxDecoration(color: theme.backgroundColor),
child: NotificationListener(
onNotification: (ScrollNotification notification) {
if (notification.depth == 0 &&
notification is ScrollEndNotification &&
notification.metrics is FixedExtentMetrics) {
final FixedExtentMetrics metrics =
notification.metrics as FixedExtentMetrics;
final int currentItemIndex = metrics.itemIndex;
selectedChangedWhenScrollEnd(currentItemIndex);
}
return false;
},
child: CupertinoPicker.builder(
key: key,
backgroundColor: theme.backgroundColor,
scrollController: scrollController as FixedExtentScrollController,
itemExtent: theme.itemHeight,
onSelectedItemChanged: (int index) {
selectedChangedWhenScrolling(index);
},
useMagnifier: false,
itemBuilder: (BuildContext context, int index) {
final content = stringAtIndexCB(index);
if (content == null) {
return null;
}
return Container(
height: theme.itemHeight,
alignment: Alignment.center,
child: Text(
content,
style: theme.itemStyle,
textAlign: TextAlign.start,
),
);
},
),
),
),
);
}
Widget _renderItemView(picker_theme.DatePickerTheme theme) {
return Container(
color: theme.backgroundColor,
child: Directionality(
textDirection: TextDirection.ltr,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// 年
Container(
child: pickerModel.layoutProportions()[0] > 0
? _renderColumnView(
ValueKey(pickerModel.currentLeftIndex()),
theme,
pickerModel.leftStringAtIndex,
leftScrollCtrl,
pickerModel.layoutProportions()[0], (index) {
pickerModel.setLeftIndex(index);
}, (index) {
setState(() {
refreshScrollOffset();
_notifyDateChanged();
});
})
: null,
),
Text(
pickerModel.leftDivider(),
style: theme.itemStyle,
),
// 月
Container(
child: pickerModel.layoutProportions()[1] > 0
? _renderColumnView(
ValueKey(pickerModel.currentLeftIndex() * 100 +
pickerModel.currentMiddleIndex()),
theme,
pickerModel.middleStringAtIndex,
middleScrollCtrl,
pickerModel.layoutProportions()[1], (index) {
pickerModel.setMiddleIndex(index);
}, (index) {
debugPrint('index: $index');
setState(() {
refreshScrollOffset();
_notifyDateChanged();
});
})
: null,
),
Text(
pickerModel.rightDivider(),
style: theme.itemStyle,
),
// 日
Container(
child: pickerModel.layoutProportions()[2] > 0
? _renderColumnView(
ValueKey(pickerModel.currentMiddleIndex() * 100 +
pickerModel.currentLeftIndex()),
theme,
pickerModel.rightStringAtIndex,
rightScrollCtrl,
pickerModel.layoutProportions()[2], (index) {
pickerModel.setRightIndex(index);
}, (index) {
setState(() {
refreshScrollOffset();
_notifyDateChanged();
});
})
: null,
),
if (widget.showTime ?? true)
Text(
pickerModel.rightDivider(),
style: theme.itemStyle,
),
if (widget.showTime ?? true)
Container(
child: pickerModel.layoutProportions()[3] > 0
? _renderColumnView(
ValueKey(pickerModel.currentMinuteIndex() * 200 +
pickerModel.currentHourIndex()),
theme,
pickerModel.hourStringAtIndex,
hourScrollCtrl,
pickerModel.layoutProportions()[3], (index) {
pickerModel.setHourIndex(index);
}, (index) {
setState(() {
refreshScrollOffset();
_notifyDateChanged();
});
})
: null,
),
if (widget.showTime ?? true)
Text(
pickerModel.timeDivider(),
style: theme.itemStyle,
),
if (widget.showTime ?? true)
Container(
child: pickerModel.layoutProportions()[4] > 0
? _renderColumnView(
ValueKey(pickerModel.currentMinuteIndex() * 100 +
pickerModel.currentHourIndex()),
theme,
pickerModel.minuteStringAtIndex,
minuteScrollCtrl,
pickerModel.layoutProportions()[4], (index) {
pickerModel.setMinuteIndex(index);
}, (index) {
setState(() {
refreshScrollOffset();
_notifyDateChanged();
});
})
: null,
),
],
),
),
);
}
// Title View
Widget _renderTitleActionsView(picker_theme.DatePickerTheme theme) {
const done = "完成";
const cancel = "取消";
return Container(
height: theme.titleHeight,
decoration: BoxDecoration(
color: theme.headerColor ?? theme.backgroundColor,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
height: theme.titleHeight,
child: CupertinoButton(
pressedOpacity: 0.3,
padding: const EdgeInsetsDirectional.only(start: 16, top: 0),
child: Text(
cancel,
style: theme.cancelStyle,
),
onPressed: () {
Navigator.pop(context);
if (widget.route.onCancel != null) {
widget.route.onCancel!();
}
},
),
),
// Container(
// decoration: BoxDecoration(
// border: Border.all(width: 1, color: theme.doneStyle.color!),
// borderRadius: const BorderRadius.all(Radius.circular(8.0)),
// ),
// child: Row(
// children: [
// TextButton(
// onPressed: () {
// onLunarChange(false);
// },
// style: ButtonStyle(
// shape: MaterialStateProperty.all(
// const RoundedRectangleBorder(
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(7),
// bottomLeft: Radius.circular(7),
// ),
// )),
// padding: MaterialStateProperty.all(EdgeInsets.zero),
// tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// minimumSize:
// MaterialStateProperty.all(const Size(50, 26)),
// backgroundColor: lunarPicker
// ? MaterialStateProperty.all(Colors.transparent)
// : MaterialStateProperty.all(theme.doneStyle.color)),
// child: Text(
// "公历",
// style: TextStyle(
// color:
// lunarPicker ? theme.doneStyle.color : Colors.white),
// ),
// ),
// TextButton(
// onPressed: () {
// onLunarChange(true);
// },
// style: ButtonStyle(
// shape: MaterialStateProperty.all(const RoundedRectangleBorder(
// borderRadius: BorderRadius.only(
// topRight: Radius.circular(7),
// bottomRight: Radius.circular(7),
// ),)),
// padding: MaterialStateProperty.all(EdgeInsets.zero),
// tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// minimumSize:
// MaterialStateProperty.all(const Size(50, 26)),
// backgroundColor: lunarPicker
// ? MaterialStateProperty.all(theme.doneStyle.color)
// : MaterialStateProperty.all(Colors.transparent)),
// child: Text("阴历",
// style: TextStyle(
// color: lunarPicker
// ? Colors.white
// : theme.doneStyle.color)),
// ),
// ],
// ),
// ),
SizedBox(
height: theme.titleHeight,
child: CupertinoButton(
pressedOpacity: 0.3,
padding: const EdgeInsetsDirectional.only(end: 16, top: 0),
child: Text(
done,
style: theme.doneStyle,
),
onPressed: () {
Navigator.pop(context, pickerModel.finalTime());
if (widget.route.onConfirm != null) {
widget.route.onConfirm!(
pickerModel.finalTime()!, lunarPicker);
}
},
),
),
],
),
);
}
}
class _BottomPickerLayout extends SingleChildLayoutDelegate {
_BottomPickerLayout(
this.progress,
this.theme, {
this.showTitleActions,
this.bottomPadding = 0,
});
final double progress;
// final int? itemCount;
final bool? showTitleActions;
final picker_theme.DatePickerTheme theme;
final double bottomPadding;
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
double maxHeight = theme.containerHeight;
if (showTitleActions == true) {
maxHeight += theme.titleHeight;
}
return BoxConstraints(
minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth,
minHeight: 0.0,
maxHeight: maxHeight + bottomPadding,
);
}
@override
Offset getPositionForChild(Size size, Size childSize) {
final height = size.height - childSize.height * progress;
return Offset(0.0, height);
}
@override
bool shouldRelayout(_BottomPickerLayout oldDelegate) {
return progress != oldDelegate.progress;
}
}
... ...
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.19.0"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.3"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
url: "https://pub.flutter-io.cn"
source: hosted
version: "10.0.7"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.8"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
lunar:
dependency: "direct main"
description:
name: lunar
sha256: "4ebb40c1647c5903fc67ff0be09a4ce90da79b482f0c78a8c727086a67375c37"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.7.5"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.15.0"
path:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.9.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.12.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.7.3"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
url: "https://pub.flutter-io.cn"
source: hosted
version: "14.3.0"
sdks:
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"
... ...
name: flutter_lunar_datetime_picker
description: A Flutter Lunar Datetime Picker ! You can dynamically switch the selection of the lunar calendar and lunar calendar.
version: 1.0.6
homepage: https://github.com/LoquatZ/flutter_lunar_datetime_picker
environment:
sdk: '>=2.12.0 <4.0.0'
flutter: ">=1.17.0"
dependencies:
flutter:
sdk: flutter
lunar: ^1.2.21
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# To add assets to your package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages
... ...
import 'package:flutter_test/flutter_test.dart';
void main() {
test('adds one to input values', () {
});
}
... ...
... ... @@ -845,6 +845,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_lunar_datetime_picker:
dependency: "direct main"
description:
path: "library/flutter_lunar_datetime_picker-1.0.6"
relative: true
source: path
version: "1.0.6"
flutter_native_contact_picker:
dependency: "direct main"
description:
... ... @@ -1215,6 +1222,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.3"
lunar:
dependency: transitive
description:
name: lunar
sha256: "4ebb40c1647c5903fc67ff0be09a4ce90da79b482f0c78a8c727086a67375c37"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.7.5"
macros:
dependency: transitive
description:
... ...
... ... @@ -241,6 +241,9 @@ dependencies:
azlistview_plus:
path: library/azlistview_plus-3.0.0
flutter_lunar_datetime_picker:
path: library/flutter_lunar_datetime_picker-1.0.6
... ... @@ -304,6 +307,8 @@ dependencies:
#表格多选组建
# flutter_awesome_select: ^6.5.0
collection: ^1.15.0-nullsafety.4
... ...