diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 9367d483..9625e105 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 8.0 + 11.0 diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index da2211a4..a71e07fe 100755 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -1,16 +1,14 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/Users/liuyanbo/flutter" -export "FLUTTER_APPLICATION_PATH=/Users/liuyanbo/Documents/GitHub/flutter_datetime_picker/example" -export "FLUTTER_TARGET=/Users/liuyanbo/Documents/GitHub/flutter_datetime_picker/example/lib/main.dart" +export "FLUTTER_ROOT=/Users/zh/Library/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/zh/Documents/gree/work/fork/flutter_datetime_picker/example" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=/Users/zh/Documents/gree/work/fork/flutter_datetime_picker/example/lib/main.dart" export "FLUTTER_BUILD_DIR=build" -export "SYMROOT=${SOURCE_ROOT}/../build/ios" -export "OTHER_LDFLAGS=$(inherited) -framework Flutter" -export "FLUTTER_FRAMEWORK_DIR=/Users/liuyanbo/flutter/bin/cache/artifacts/engine/ios" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" -export "DART_DEFINES=flutter.inspector.structuredErrors%3Dtrue" +export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==" export "DART_OBFUSCATION=false" export "TRACK_WIDGET_CREATION=true" export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=.packages" +export "PACKAGE_CONFIG=/Users/zh/Documents/gree/work/fork/flutter_datetime_picker/example/.dart_tool/package_config.json" diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 1c85b6d7..3d4f0cb6 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -140,7 +140,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0910; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -184,6 +184,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -198,6 +199,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -290,7 +292,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -337,7 +339,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16..919434a6 100644 --- a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 1263ac84..1c19f4b8 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ UIViewControllerBasedStatusBarAppearance + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + diff --git a/example/lib/main.dart b/example/lib/main.dart index 1ab0e793..5c7bcdc8 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -8,8 +8,7 @@ class CustomPicker extends CommonPickerModel { return '$value'.padLeft(length, "0"); } - CustomPicker({DateTime? currentTime, LocaleType? locale}) - : super(locale: locale) { + CustomPicker({DateTime? currentTime, LocaleType? locale}) : super(locale: locale) { this.currentTime = currentTime ?? DateTime.now(); this.setLeftIndex(this.currentTime.hour); this.setMiddleIndex(this.currentTime.minute); @@ -45,36 +44,26 @@ class CustomPicker extends CommonPickerModel { @override String leftDivider() { - return "|"; + return ""; } @override String rightDivider() { - return "|"; + return ""; } @override List layoutProportions() { - return [1, 2, 1]; + return [2, 1, 1]; } @override DateTime finalTime() { return currentTime.isUtc ? DateTime.utc( - currentTime.year, - currentTime.month, - currentTime.day, - this.currentLeftIndex(), - this.currentMiddleIndex(), - this.currentRightIndex()) + currentTime.year, currentTime.month, currentTime.day, this.currentLeftIndex(), this.currentMiddleIndex(), this.currentRightIndex()) : DateTime( - currentTime.year, - currentTime.month, - currentTime.day, - this.currentLeftIndex(), - this.currentMiddleIndex(), - this.currentRightIndex()); + currentTime.year, currentTime.month, currentTime.day, this.currentLeftIndex(), this.currentMiddleIndex(), this.currentRightIndex()); } } @@ -102,154 +91,148 @@ class HomePage extends StatelessWidget { body: Center( child: Column( children: [ + // TextButton( + // onPressed: () { + // DatePicker.showDatePicker(context, + // showTitleActions: true, + // minTime: DateTime(2018, 3, 5), + // maxTime: DateTime(2019, 6, 7), + // theme: DatePickerTheme( + // headerColor: Colors.orange, + // backgroundColor: Colors.blue, + // itemStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 18), + // doneStyle: TextStyle(color: Colors.white, fontSize: 16)), onChanged: (date) { + // print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + // }, onConfirm: (date) { + // print('confirm $date'); + // }, currentTime: DateTime.now(), locale: LocaleType.en); + // }, + // child: Text( + // 'show date picker(custom theme &date time range)', + // style: TextStyle(color: Colors.blue), + // )), + // TextButton( + // onPressed: () { + // DatePicker.showTimePicker(context, showTitleActions: true, onChanged: (date) { + // print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + // }, onConfirm: (date) { + // print('confirm $date'); + // }, currentTime: DateTime.now()); + // }, + // child: Text( + // 'show time picker', + // style: TextStyle(color: Colors.blue), + // )), + // TextButton( + // onPressed: () { + // DatePicker.showTime12hPicker(context, showTitleActions: true, onChanged: (date) { + // print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + // }, onConfirm: (date) { + // print('confirm $date'); + // }, currentTime: DateTime.now()); + // }, + // child: Text( + // 'show 12H time picker with AM/PM', + // style: TextStyle(color: Colors.blue), + // )), TextButton( onPressed: () { - DatePicker.showDatePicker(context, - showTitleActions: true, - minTime: DateTime(2018, 3, 5), - maxTime: DateTime(2019, 6, 7), - theme: DatePickerTheme( - headerColor: Colors.orange, - backgroundColor: Colors.blue, - itemStyle: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 18), - doneStyle: - TextStyle(color: Colors.white, fontSize: 16)), - onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, currentTime: DateTime.now(), locale: LocaleType.en); - }, - child: Text( - 'show date picker(custom theme &date time range)', - style: TextStyle(color: Colors.blue), - )), - TextButton( - onPressed: () { - DatePicker.showTimePicker(context, showTitleActions: true, - onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, currentTime: DateTime.now()); - }, - child: Text( - 'show time picker', - style: TextStyle(color: Colors.blue), - )), - TextButton( - onPressed: () { - DatePicker.showTime12hPicker(context, showTitleActions: true, - onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, currentTime: DateTime.now()); - }, - child: Text( - 'show 12H time picker with AM/PM', - style: TextStyle(color: Colors.blue), - )), - TextButton( - onPressed: () { - DatePicker.showDateTimePicker(context, - showTitleActions: true, - minTime: DateTime(2020, 5, 5, 20, 50), - maxTime: DateTime(2020, 6, 7, 05, 09), onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, locale: LocaleType.zh); - }, - child: Text( - 'show date time picker (Chinese)', - style: TextStyle(color: Colors.blue), - )), - TextButton( - onPressed: () { - DatePicker.showDateTimePicker(context, showTitleActions: true, - onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, currentTime: DateTime(2008, 12, 31, 23, 12, 34)); - }, - child: Text( - 'show date time picker (English-America)', - style: TextStyle(color: Colors.blue), - )), - TextButton( - onPressed: () { - DatePicker.showDateTimePicker(context, showTitleActions: true, - onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, - currentTime: DateTime(2008, 12, 31, 23, 12, 34), - locale: LocaleType.nl); - }, - child: Text( - 'show date time picker (Dutch)', - style: TextStyle(color: Colors.blue), - )), - TextButton( - onPressed: () { - DatePicker.showDateTimePicker(context, showTitleActions: true, - onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, - currentTime: DateTime(2008, 12, 31, 23, 12, 34), - locale: LocaleType.ru); - }, - child: Text( - 'show date time picker (Russian)', - style: TextStyle(color: Colors.blue), - )), - TextButton( - onPressed: () { - DatePicker.showDateTimePicker(context, showTitleActions: true, - onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, - currentTime: DateTime.utc(2019, 12, 31, 23, 12, 34), - locale: LocaleType.de); - }, - child: Text( - 'show date time picker in UTC (German)', - style: TextStyle(color: Colors.blue), - )), - TextButton( - onPressed: () { - DatePicker.showPicker(context, showTitleActions: true, - onChanged: (date) { - print('change $date in time zone ' + - date.timeZoneOffset.inHours.toString()); - }, onConfirm: (date) { - print('confirm $date'); - }, - pickerModel: CustomPicker(currentTime: DateTime.now()), - locale: LocaleType.en); + DatePicker.showGreeRouteDateTimePicker( + context, + showTitleActions: true, + minTime: DateTime(2023, 3, 9, 8, 12), + maxTime: DateTime(2023, 3, 10, 7, 11), + theme: DatePickerTheme(title: '开始时间'), + onChanged: (date) { + print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + }, + onConfirm: (date) { + print('confirm $date'); + }, + locale: LocaleType.zh, + ).then((date) { + + print('当前时间 $date'); + + }); }, child: Text( - 'show custom time picker,\nyou can custom picker model like this', + '导航 DatePicker', style: TextStyle(color: Colors.blue), )), + // TextButton( + // onPressed: () { + // DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) { + // print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + // }, onConfirm: (date) { + // print('confirm $date'); + // }, currentTime: DateTime(2008, 12, 31, 23, 12, 34)); + // }, + // child: Text( + // 'show date time picker (English-America)', + // style: TextStyle(color: Colors.blue), + // )), + // TextButton( + // onPressed: () { + // DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) { + // print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + // }, onConfirm: (date) { + // print('confirm $date'); + // }, currentTime: DateTime(2008, 12, 31, 23, 12, 34), locale: LocaleType.nl); + // }, + // child: Text( + // 'show date time picker (Dutch)', + // style: TextStyle(color: Colors.blue), + // )), + // TextButton( + // onPressed: () { + // DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) { + // print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + // }, onConfirm: (date) { + // print('confirm $date'); + // }, currentTime: DateTime(2008, 12, 31, 23, 12, 34), locale: LocaleType.ru); + // }, + // child: Text( + // 'show date time picker (Russian)', + // style: TextStyle(color: Colors.blue), + // )), + // TextButton( + // onPressed: () { + // DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) { + // print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + // }, onConfirm: (date) { + // print('confirm $date'); + // }, currentTime: DateTime.utc(2019, 12, 31, 23, 12, 34), locale: LocaleType.de); + // }, + // child: Text( + // 'show date time picker in UTC (German)', + // style: TextStyle(color: Colors.blue), + // )), + // TextButton( + // onPressed: () { + // DatePicker.showPicker(context, showTitleActions: true, onChanged: (date) { + // print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); + // }, onConfirm: (date) { + // print('confirm $date'); + // }, pickerModel: CustomPicker(currentTime: DateTime.now()), locale: LocaleType.en); + // }, + // child: Text( + // 'show custom time picker,\nyou can custom picker model like this', + // style: TextStyle(color: Colors.blue), + // )), + // TextButton( + // onPressed: () { + // DatePicker.showPicker( + // context, + // pickerModel: CustomPicker(locale: LocaleType.zh), + // onChanged: (date) {}, + // onConfirm: (date) {}, + // ); + // }, + // child: Text( + // '路线规划 DatePicker', + // style: TextStyle(color: Colors.blue), + // )), ], ), ), diff --git a/lib/base_popup_route.dart b/lib/base_popup_route.dart new file mode 100644 index 00000000..712dc9b4 --- /dev/null +++ b/lib/base_popup_route.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; + +class TestInfo { + String? name; +} + +class GMDialog { + static Future showDialog(BuildContext context) async { + return await Navigator.push(context, GMBasePopupRoute()); + } +} + +class GMBasePopupRoute extends PopupRoute { + @override + Color? get barrierColor => Colors.black54; + + @override + bool get barrierDismissible => true; + + @override + String? barrierLabel; + + @override + Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { + Widget bottom = MediaQuery.removePadding( + context: context, + removeTop: true, + child: Container( + color: Colors.red, + height: 300, + )); + return InheritedTheme.captureAll(context, bottom); + } + + @override + Duration get transitionDuration => const Duration(milliseconds: 250); +} diff --git a/lib/flutter_datetime_picker.dart b/lib/flutter_datetime_picker.dart index dba6b566..20f43d2f 100644 --- a/lib/flutter_datetime_picker.dart +++ b/lib/flutter_datetime_picker.dart @@ -4,6 +4,7 @@ import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/painting.dart'; +import 'package:flutter_datetime_picker/src/gree_route_date_picker_model.dart'; import 'package:flutter_datetime_picker/src/datetime_picker_theme.dart'; import 'package:flutter_datetime_picker/src/date_model.dart'; import 'package:flutter_datetime_picker/src/i18n_model.dart'; @@ -17,112 +18,12 @@ typedef DateCancelledCallback(); typedef String? StringAtIndexCallBack(int index); class DatePicker { - /// - /// Display date picker bottom sheet. - /// - static Future showDatePicker( - BuildContext context, { - bool showTitleActions: true, - DateTime? minTime, - DateTime? maxTime, - DateChangedCallback? onChanged, - DateChangedCallback? onConfirm, - DateCancelledCallback? onCancel, - locale: LocaleType.en, - DateTime? currentTime, - DatePickerTheme? theme, - }) async { - return await Navigator.push( - context, - _DatePickerRoute( - showTitleActions: showTitleActions, - onChanged: onChanged, - onConfirm: onConfirm, - onCancel: onCancel, - locale: locale, - theme: theme, - barrierLabel: - MaterialLocalizations.of(context).modalBarrierDismissLabel, - pickerModel: DatePickerModel( - currentTime: currentTime, - maxTime: maxTime, - minTime: minTime, - locale: locale, - ), - ), - ); - } - - /// - /// Display time picker bottom sheet. - /// - static Future showTimePicker( - BuildContext context, { - bool showTitleActions: true, - bool showSecondsColumn: true, - DateChangedCallback? onChanged, - DateChangedCallback? onConfirm, - DateCancelledCallback? onCancel, - locale: LocaleType.en, - DateTime? currentTime, - DatePickerTheme? theme, - }) async { - return await Navigator.push( - context, - _DatePickerRoute( - showTitleActions: showTitleActions, - onChanged: onChanged, - onConfirm: onConfirm, - onCancel: onCancel, - locale: locale, - theme: theme, - barrierLabel: - MaterialLocalizations.of(context).modalBarrierDismissLabel, - pickerModel: TimePickerModel( - currentTime: currentTime, - locale: locale, - showSecondsColumn: showSecondsColumn, - ), - ), - ); - } - - /// - /// Display time picker bottom sheet with AM/PM. - /// - static Future showTime12hPicker( - BuildContext context, { - bool showTitleActions: true, - DateChangedCallback? onChanged, - DateChangedCallback? onConfirm, - DateCancelledCallback? onCancel, - locale: LocaleType.en, - DateTime? currentTime, - DatePickerTheme? theme, - }) async { - return await Navigator.push( - context, - _DatePickerRoute( - showTitleActions: showTitleActions, - onChanged: onChanged, - onConfirm: onConfirm, - onCancel: onCancel, - locale: locale, - theme: theme, - barrierLabel: - MaterialLocalizations.of(context).modalBarrierDismissLabel, - pickerModel: Time12hPickerModel( - currentTime: currentTime, - locale: locale, - ), - ), - ); - } - /// - /// Display date&time picker bottom sheet. - /// - static Future showDateTimePicker( + /* + * + * 路径规划时间日期选择器 + * */ + static Future showGreeRouteDateTimePicker( BuildContext context, { bool showTitleActions: true, DateTime? minTime, @@ -143,9 +44,8 @@ class DatePicker { onCancel: onCancel, locale: locale, theme: theme, - barrierLabel: - MaterialLocalizations.of(context).modalBarrierDismissLabel, - pickerModel: DateTimePickerModel( + barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, + pickerModel: GreeRouteDatePickerModel( currentTime: currentTime, minTime: minTime, maxTime: maxTime, @@ -154,35 +54,6 @@ class DatePicker { ), ); } - - /// - /// Display date picker bottom sheet witch custom picker model. - /// - static Future showPicker( - BuildContext context, { - bool showTitleActions: true, - DateChangedCallback? onChanged, - DateChangedCallback? onConfirm, - DateCancelledCallback? onCancel, - locale: LocaleType.en, - BasePickerModel? pickerModel, - DatePickerTheme? theme, - }) async { - return await Navigator.push( - context, - _DatePickerRoute( - showTitleActions: showTitleActions, - onChanged: onChanged, - onConfirm: onConfirm, - onCancel: onCancel, - locale: locale, - theme: theme, - barrierLabel: - MaterialLocalizations.of(context).modalBarrierDismissLabel, - pickerModel: pickerModel, - ), - ); - } } class _DatePickerRoute extends PopupRoute { @@ -212,7 +83,7 @@ class _DatePickerRoute extends PopupRoute { Duration get transitionDuration => const Duration(milliseconds: 200); @override - bool get barrierDismissible => true; + bool get barrierDismissible => false; @override final String? barrierLabel; @@ -225,14 +96,12 @@ class _DatePickerRoute extends PopupRoute { @override AnimationController createAnimationController() { assert(_animationController == null); - _animationController = - BottomSheet.createAnimationController(navigator!.overlay!); + _animationController = BottomSheet.createAnimationController(navigator!.overlay!); return _animationController!; } @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { + Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { Widget bottomSheet = MediaQuery.removePadding( context: context, removeTop: true, @@ -271,9 +140,7 @@ class _DatePickerComponent extends StatefulWidget { } class _DatePickerState extends State<_DatePickerComponent> { - late FixedExtentScrollController leftScrollCtrl, - middleScrollCtrl, - rightScrollCtrl; + late FixedExtentScrollController leftScrollCtrl, middleScrollCtrl, rightScrollCtrl; @override void initState() { @@ -283,12 +150,9 @@ class _DatePickerState extends State<_DatePickerComponent> { void refreshScrollOffset() { // print('refreshScrollOffset ${widget.pickerModel.currentRightIndex()}'); - leftScrollCtrl = FixedExtentScrollController( - initialItem: widget.pickerModel.currentLeftIndex()); - middleScrollCtrl = FixedExtentScrollController( - initialItem: widget.pickerModel.currentMiddleIndex()); - rightScrollCtrl = FixedExtentScrollController( - initialItem: widget.pickerModel.currentRightIndex()); + leftScrollCtrl = FixedExtentScrollController(initialItem: widget.pickerModel.currentLeftIndex()); + middleScrollCtrl = FixedExtentScrollController(initialItem: widget.pickerModel.currentMiddleIndex()); + rightScrollCtrl = FixedExtentScrollController(initialItem: widget.pickerModel.currentRightIndex()); } @override @@ -309,7 +173,7 @@ class _DatePickerState extends State<_DatePickerComponent> { ), child: GestureDetector( child: Material( - color: theme.backgroundColor, + color: Colors.transparent, child: _renderPickerView(theme), ), ), @@ -333,12 +197,35 @@ class _DatePickerState extends State<_DatePickerComponent> { children: [ _renderTitleActionsView(theme), itemView, + Expanded( + child: Container(color: theme.backgroundColor), + ) ], ); } return itemView; } + /// 上下分割线 + Widget _buildMagnifierScreen(double itemExtent) { + final Color resolvedBorderColor = CupertinoDynamicColor.resolve(Color(0xFFEBEDF5), context); + return IgnorePointer( + child: Center( + child: Container( + decoration: BoxDecoration( + border: Border( + top: BorderSide(width: 0.0, color: resolvedBorderColor), + bottom: BorderSide(width: 0.0, color: resolvedBorderColor), + ), + ), + constraints: BoxConstraints.expand( + height: itemExtent, + ), + ), + ), + ); + } + Widget _renderColumnView( ValueKey key, DatePickerTheme theme, @@ -351,16 +238,12 @@ class _DatePickerState extends State<_DatePickerComponent> { return Expanded( flex: layoutProportion, child: Container( - padding: EdgeInsets.all(8.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; + 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); } @@ -369,6 +252,7 @@ class _DatePickerState extends State<_DatePickerComponent> { child: CupertinoPicker.builder( key: key, backgroundColor: theme.backgroundColor, + selectionOverlay: _buildMagnifierScreen(theme.itemHeight), scrollController: scrollController as FixedExtentScrollController, itemExtent: theme.itemHeight, onSelectedItemChanged: (int index) { @@ -406,11 +290,7 @@ class _DatePickerState extends State<_DatePickerComponent> { children: [ Container( child: widget.pickerModel.layoutProportions()[0] > 0 - ? _renderColumnView( - ValueKey(widget.pickerModel.currentLeftIndex()), - theme, - widget.pickerModel.leftStringAtIndex, - leftScrollCtrl, + ? _renderColumnView(ValueKey(widget.pickerModel.currentLeftIndex()), theme, widget.pickerModel.leftStringAtIndex, leftScrollCtrl, widget.pickerModel.layoutProportions()[0], (index) { widget.pickerModel.setLeftIndex(index); }, (index) { @@ -427,12 +307,8 @@ class _DatePickerState extends State<_DatePickerComponent> { ), Container( child: widget.pickerModel.layoutProportions()[1] > 0 - ? _renderColumnView( - ValueKey(widget.pickerModel.currentLeftIndex()), - theme, - widget.pickerModel.middleStringAtIndex, - middleScrollCtrl, - widget.pickerModel.layoutProportions()[1], (index) { + ? _renderColumnView(ValueKey(widget.pickerModel.currentLeftIndex()), theme, widget.pickerModel.middleStringAtIndex, + middleScrollCtrl, widget.pickerModel.layoutProportions()[1], (index) { widget.pickerModel.setMiddleIndex(index); }, (index) { setState(() { @@ -448,13 +324,8 @@ class _DatePickerState extends State<_DatePickerComponent> { ), Container( child: widget.pickerModel.layoutProportions()[2] > 0 - ? _renderColumnView( - ValueKey(widget.pickerModel.currentMiddleIndex() * 100 + - widget.pickerModel.currentLeftIndex()), - theme, - widget.pickerModel.rightStringAtIndex, - rightScrollCtrl, - widget.pickerModel.layoutProportions()[2], (index) { + ? _renderColumnView(ValueKey(widget.pickerModel.currentMiddleIndex() * 100 + widget.pickerModel.currentLeftIndex()), theme, + widget.pickerModel.rightStringAtIndex, rightScrollCtrl, widget.pickerModel.layoutProportions()[2], (index) { widget.pickerModel.setRightIndex(index); }, (index) { setState(() { @@ -472,51 +343,51 @@ class _DatePickerState extends State<_DatePickerComponent> { // Title View Widget _renderTitleActionsView(DatePickerTheme theme) { - final done = _localeDone(); final cancel = _localeCancel(); - return Container( height: theme.titleHeight, decoration: BoxDecoration( - color: theme.headerColor ?? theme.backgroundColor, + color: theme.headerColor, + borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - height: theme.titleHeight, - child: CupertinoButton( - pressedOpacity: 0.3, - padding: EdgeInsetsDirectional.only(start: 16, top: 0), - child: Text( - '$cancel', - style: theme.cancelStyle, + child: Column( + children: [ + Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Container( + margin: const EdgeInsets.only(left: 66), + alignment: Alignment.center, + height: theme.titleHeight - 1, + child: Text( + theme.title, + style: theme.titleStyle, + ), + ), ), - onPressed: () { - Navigator.pop(context); - if (widget.route.onCancel != null) { - widget.route.onCancel!(); - } - }, - ), - ), - Container( - height: theme.titleHeight, - child: CupertinoButton( - pressedOpacity: 0.3, - padding: EdgeInsetsDirectional.only(end: 16, top: 0), - child: Text( - '$done', - style: theme.doneStyle, + Container( + margin: const EdgeInsets.only(right: 16), + alignment: Alignment.centerRight, + height: theme.titleHeight - 1, + child: CupertinoButton( + pressedOpacity: 0.3, + padding: EdgeInsetsDirectional.only(start: 16, top: 0), + child: Text( + '$cancel', + style: theme.cancelStyle, + ), + onPressed: () { + Navigator.pop(context, widget.pickerModel.finalTime()); + if (widget.route.onCancel != null) { + widget.route.onCancel!(); + } + }, + ), ), - onPressed: () { - Navigator.pop(context, widget.pickerModel.finalTime()); - if (widget.route.onConfirm != null) { - widget.route.onConfirm!(widget.pickerModel.finalTime()!); - } - }, - ), + ], ), + Container(height: 1, color: Color(0xFFEBEDF5)), ], ), ); @@ -527,7 +398,8 @@ class _DatePickerState extends State<_DatePickerComponent> { } String _localeCancel() { - return i18nObjInLocale(widget.locale)['cancel'] as String; + return '关闭'; + // return i18nObjInLocale(widget.locale)['cancel'] as String; } } diff --git a/lib/src/date_model.dart b/lib/src/date_model.dart index 0e899870..7bf98f1d 100644 --- a/lib/src/date_model.dart +++ b/lib/src/date_model.dart @@ -626,6 +626,8 @@ class DateTimePickerModel extends CommonPickerModel { String? middleStringAtIndex(int index) { if (index >= 0 && index < 24) { DateTime time = currentTime.add(Duration(days: _currentLeftIndex)); + + if (isAtSameDay(minTime, time)) { if (index >= 0 && index < 24 - minTime!.hour) { return digits(minTime!.hour + index, 2); diff --git a/lib/src/datetime_picker_theme.dart b/lib/src/datetime_picker_theme.dart index e3f616f4..0e84a7e0 100644 --- a/lib/src/datetime_picker_theme.dart +++ b/lib/src/datetime_picker_theme.dart @@ -7,21 +7,24 @@ class DatePickerTheme with DiagnosticableTreeMixin { final TextStyle cancelStyle; final TextStyle doneStyle; final TextStyle itemStyle; + final TextStyle titleStyle; + final String title; final Color backgroundColor; - final Color? headerColor; - + 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.cancelStyle = const TextStyle(color: Color(0xFF409EFF), fontSize: 16), + this.doneStyle = const TextStyle(color: Colors.black, fontSize: 16), + this.itemStyle = const TextStyle(color: Color(0xFF333333), fontSize: 18), + this.titleStyle = const TextStyle(color: Color(0xFF333333), fontSize: 18, fontWeight: FontWeight.w600), + this.title = '', this.backgroundColor = Colors.white, - this.headerColor, - this.containerHeight = 210.0, - this.titleHeight = 44.0, - this.itemHeight = 36.0, + this.headerColor = Colors.white, + this.containerHeight = 330.0, + this.titleHeight = 74.0, + this.itemHeight = 48.0, }); } diff --git a/lib/src/gree_route_date_picker_model.dart b/lib/src/gree_route_date_picker_model.dart new file mode 100644 index 00000000..321a7114 --- /dev/null +++ b/lib/src/gree_route_date_picker_model.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:flutter_datetime_picker/src/date_format.dart'; + +class GreeRouteDatePickerModel extends DateTimePickerModel { + GreeRouteDatePickerModel({ + DateTime? currentTime, + DateTime? maxTime, + DateTime? minTime, + LocaleType? locale, + }) : super( + currentTime: currentTime, + maxTime: maxTime, + minTime: minTime, + locale: locale, + ); + + @override + String? middleStringAtIndex(int index) { + String? hour = super.middleStringAtIndex(index); + + /// 修复时间为同一天的显示bug + if (isAtSameDay(maxTime, minTime)) { + // hour + if (int.parse(hour ?? '0') <= (maxTime?.hour ?? 0) && int.parse(hour ?? '0') >= (minTime?.hour ?? 0)) { + return hour == null ? null : '$hour 时'; + } + return null; + } + return hour == null ? null : '$hour 时'; + } + + @override + String? rightStringAtIndex(int index) { + String? minute = super.rightStringAtIndex(index); + int hour = finalTime().hour; + + /// min max 为同一天 + if (isAtSameDay(maxTime, minTime)) { + if (hour < (maxTime?.hour ?? 0)) { + return minute == null ? null : '$minute 分'; + } + + /// min hour 大于最小 minute + if ((minTime?.hour ?? 0) == hour && minute != null) { + int _minute = int.parse(minute); + if (_minute >= (minTime?.minute ?? 0) && _minute <= (maxTime?.minute ?? 0)) { + return '$minute 分'; + } + return null; + } + + /// max hour 小于最大 minute + if ((maxTime?.hour ?? 0) == hour && minute != null) { + print('${int.parse(minute)} ${maxTime?.minute ?? 0} ${int.parse(minute) <= (maxTime?.minute ?? 0)}'); + return int.parse(minute) <= (maxTime?.minute ?? 0) ? '$minute 分' : null; + } + } + return minute == null ? null : '$minute 分'; + } + + @override + String? leftStringAtIndex(int index) { + DateTime time = currentTime.add(Duration(days: index)); + if (minTime != null && time.isBefore(minTime!) && !isAtSameDay(minTime!, time)) { + return null; + } else if (maxTime != null && time.isAfter(maxTime!) && !isAtSameDay(maxTime, time)) { + return null; + } + return '${time.year}年${time.month}月${time.day}日'; + } + + @override + List layoutProportions() { + return [2, 1, 1]; + } + + @override + String leftDivider() { + return ''; + } + + @override + String rightDivider() { + return ''; + } +}