flutter_rounded_date_picker files from picker lib

This commit is contained in:
ryleedavis 2022-11-28 13:50:55 -07:00
parent c3921b01de
commit b4cbf078c7
2 changed files with 548 additions and 0 deletions

View file

@ -0,0 +1,332 @@
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
import 'package:flutter/services.dart';
import 'package:flutter_rounded_date_picker/flutter_rounded_date_picker.dart';
import 'package:flutter_rounded_date_picker/src/flutter_rounded_button_action.dart';
import 'package:flutter_rounded_date_picker/src/material_rounded_date_picker_style.dart';
import 'package:flutter_rounded_date_picker/src/material_rounded_year_picker_style.dart';
import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_date_picker_header.dart';
import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_day_picker.dart';
import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_month_picker.dart';
import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_year_picker.dart';
import 'package:stackwallet/utilities/util.dart';
///
/// This file uses code taken from https://github.com/benznest/flutter_rounded_date_picker
///
class FlutterRoundedDatePickerDialog extends StatefulWidget {
const FlutterRoundedDatePickerDialog(
{Key? key,
this.height,
required this.initialDate,
required this.firstDate,
required this.lastDate,
this.selectableDayPredicate,
required this.initialDatePickerMode,
required this.era,
this.locale,
required this.borderRadius,
this.imageHeader,
this.description = "",
this.fontFamily,
this.textNegativeButton,
this.textPositiveButton,
this.textActionButton,
this.onTapActionButton,
this.styleDatePicker,
this.styleYearPicker,
this.customWeekDays,
this.builderDay,
this.listDateDisabled,
this.onTapDay,
this.onMonthChange})
: super(key: key);
final DateTime initialDate;
final DateTime firstDate;
final DateTime lastDate;
final SelectableDayPredicate? selectableDayPredicate;
final DatePickerMode initialDatePickerMode;
/// double height.
final double? height;
/// Custom era year.
final EraMode era;
final Locale? locale;
/// Border
final double borderRadius;
/// Header;
final ImageProvider? imageHeader;
final String description;
/// Font
final String? fontFamily;
/// Button
final String? textNegativeButton;
final String? textPositiveButton;
final String? textActionButton;
final VoidCallback? onTapActionButton;
/// Style
final MaterialRoundedDatePickerStyle? styleDatePicker;
final MaterialRoundedYearPickerStyle? styleYearPicker;
/// Custom Weekday
final List<String>? customWeekDays;
final BuilderDayOfDatePicker? builderDay;
final List<DateTime>? listDateDisabled;
final OnTapDay? onTapDay;
final Function? onMonthChange;
@override
_FlutterRoundedDatePickerDialogState createState() =>
_FlutterRoundedDatePickerDialogState();
}
class _FlutterRoundedDatePickerDialogState
extends State<FlutterRoundedDatePickerDialog> {
@override
void initState() {
super.initState();
_selectedDate = widget.initialDate;
_mode = widget.initialDatePickerMode;
}
bool _announcedInitialDate = false;
late MaterialLocalizations localizations;
late TextDirection textDirection;
@override
void didChangeDependencies() {
super.didChangeDependencies();
localizations = MaterialLocalizations.of(context);
textDirection = Directionality.of(context);
if (!_announcedInitialDate) {
_announcedInitialDate = true;
SemanticsService.announce(
localizations.formatFullDate(_selectedDate),
textDirection,
);
}
}
late DateTime _selectedDate;
late DatePickerMode _mode;
final GlobalKey _pickerKey = GlobalKey();
void _vibrate() {
switch (Theme.of(context).platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
HapticFeedback.vibrate();
break;
case TargetPlatform.iOS:
default:
break;
}
}
void _handleModeChanged(DatePickerMode mode) {
_vibrate();
setState(() {
_mode = mode;
if (_mode == DatePickerMode.day) {
SemanticsService.announce(
localizations.formatMonthYear(_selectedDate),
textDirection,
);
} else {
SemanticsService.announce(
localizations.formatYear(_selectedDate),
textDirection,
);
}
});
}
Future<void> _handleYearChanged(DateTime value) async {
if (value.isBefore(widget.firstDate)) {
value = widget.firstDate;
} else if (value.isAfter(widget.lastDate)) {
value = widget.lastDate;
}
if (value == _selectedDate) return;
if (widget.onMonthChange != null) await widget.onMonthChange!(value);
_vibrate();
setState(() {
_mode = DatePickerMode.day;
_selectedDate = value;
});
}
void _handleDayChanged(DateTime value) {
_vibrate();
setState(() {
_selectedDate = value;
});
}
void _handleCancel() {
Navigator.of(context).pop();
}
void _handleOk() {
Navigator.of(context).pop(_selectedDate);
}
Widget _buildPicker() {
switch (_mode) {
case DatePickerMode.year:
return FlutterRoundedYearPicker(
key: _pickerKey,
selectedDate: _selectedDate,
onChanged: (DateTime date) async => await _handleYearChanged(date),
firstDate: widget.firstDate,
lastDate: widget.lastDate,
era: widget.era,
fontFamily: widget.fontFamily,
style: widget.styleYearPicker,
);
case DatePickerMode.day:
default:
return FlutterRoundedMonthPicker(
key: _pickerKey,
selectedDate: _selectedDate,
onChanged: _handleDayChanged,
firstDate: widget.firstDate,
lastDate: widget.lastDate,
era: widget.era,
locale: widget.locale,
selectableDayPredicate: widget.selectableDayPredicate,
fontFamily: widget.fontFamily,
style: widget.styleDatePicker,
borderRadius: widget.borderRadius,
customWeekDays: widget.customWeekDays,
builderDay: widget.builderDay,
listDateDisabled: widget.listDateDisabled,
onTapDay: widget.onTapDay,
onMonthChange: widget.onMonthChange);
}
}
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final Widget picker = _buildPicker();
final isDesktop = Util.isDesktop;
final Widget actions = FlutterRoundedButtonAction(
textButtonNegative: widget.textNegativeButton,
textButtonPositive: widget.textPositiveButton,
onTapButtonNegative: _handleCancel,
onTapButtonPositive: _handleOk,
textActionButton: widget.textActionButton,
onTapButtonAction: widget.onTapActionButton,
localizations: localizations,
textStyleButtonNegative: widget.styleDatePicker?.textStyleButtonNegative,
textStyleButtonPositive: widget.styleDatePicker?.textStyleButtonPositive,
textStyleButtonAction: widget.styleDatePicker?.textStyleButtonAction,
borderRadius: widget.borderRadius,
paddingActionBar: widget.styleDatePicker?.paddingActionBar,
background: widget.styleDatePicker?.backgroundActionBar,
);
Color backgroundPicker = theme.dialogBackgroundColor;
if (_mode == DatePickerMode.day) {
backgroundPicker = widget.styleDatePicker?.backgroundPicker ??
theme.dialogBackgroundColor;
} else {
backgroundPicker = widget.styleYearPicker?.backgroundPicker ??
theme.dialogBackgroundColor;
}
final Dialog dialog = Dialog(
child: OrientationBuilder(
builder: (BuildContext context, Orientation orientation) {
final Widget header = FlutterRoundedDatePickerHeader(
selectedDate: _selectedDate,
mode: _mode,
onModeChanged: _handleModeChanged,
orientation: orientation,
era: widget.era,
borderRadius: widget.borderRadius,
imageHeader: widget.imageHeader,
description: widget.description,
fontFamily: widget.fontFamily,
style: widget.styleDatePicker);
switch (orientation) {
case Orientation.landscape:
return Container(
height: isDesktop ? 600 : null,
width: isDesktop ? 700 : null,
decoration: BoxDecoration(
color: backgroundPicker,
borderRadius: BorderRadius.circular(widget.borderRadius),
),
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Flexible(flex: 1, child: header),
Flexible(
flex: 2, // have the picker take up 2/3 of the dialog width
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(
height: isDesktop ? 530 : null,
width: isDesktop ? 700 : null,
child: picker),
actions,
],
),
),
],
),
);
case Orientation.portrait:
default:
return Container(
decoration: BoxDecoration(
color: backgroundPicker,
borderRadius: BorderRadius.circular(widget.borderRadius),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
header,
if (widget.height == null)
Flexible(child: picker)
else
SizedBox(
height: widget.height,
child: picker,
),
actions,
],
),
);
}
}),
);
return Theme(
data: theme.copyWith(dialogBackgroundColor: Colors.transparent),
child: dialog,
);
}
}

View file

@ -0,0 +1,216 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
// import 'package:flutter_rounded_date_picker/src/dialogs/flutter_rounded_date_picker_dialog.dart';
import 'package:flutter_rounded_date_picker/src/era_mode.dart';
import 'package:flutter_rounded_date_picker/src/material_rounded_date_picker_style.dart';
import 'package:flutter_rounded_date_picker/src/material_rounded_year_picker_style.dart';
import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_day_picker.dart';
import 'package:stackwallet/widgets/rounded_date_picker/flutter_rounded_date_picker_dialog.dart';
///
/// This file uses code taken from https://github.com/benznest/flutter_rounded_date_picker
///
// Examples can assume:
// BuildContext context;
/// Initial display mode of the date picker dialog.
///
/// Date picker UI mode for either showing a list of available years or a
/// monthly calendar initially in the dialog shown by calling [showDatePicker].
///
// Shows the selected date in large font and toggles between year and day mode
/// Signature for predicating dates for enabled date selections.
///
/// See [showDatePicker].
typedef SelectableDayPredicate = bool Function(DateTime day);
/// Shows a dialog containing a material design date picker.
///
/// The returned [Future] resolves to the date selected by the user when the
/// user closes the dialog. If the user cancels the dialog, null is returned.
///
/// An optional [selectableDayPredicate] function can be passed in to customize
/// the days to enable for selection. If provided, only the days that
/// [selectableDayPredicate] returned true for will be selectable.
///
/// An optional [initialDatePickerMode] argument can be used to display the
/// date picker initially in the year or month+day picker mode. It defaults
/// to month+day, and must not be null.
///
/// An optional [locale] argument can be used to set the locale for the date
/// picker. It defaults to the ambient locale provided by [Localizations].
///
/// An optional [textDirection] argument can be used to set the text direction
/// (RTL or LTR) for the date picker. It defaults to the ambient text direction
/// provided by [Directionality]. If both [locale] and [textDirection] are not
/// null, [textDirection] overrides the direction chosen for the [locale].
///
/// The [context] argument is passed to [showDialog], the documentation for
/// which discusses how it is used.
///
/// The [builder] parameter can be used to wrap the dialog widget
/// to add inherited widgets like [Theme].
///
/// {@tool sample}
/// Show a date picker with the dark theme.
///
/// ```dart
/// Future<DateTime> selectedDate = showDatePicker(
/// context: context,
/// initialDate: DateTime.now(),
/// firstDate: DateTime(2018),
/// lastDate: DateTime(2030),
/// builder: (BuildContext context, Widget child) {
/// return Theme(
/// data: ThemeData.dark(),
/// child: child,
/// );
/// },
/// );
/// ```
/// {@end-tool}
///
/// The [context], [initialDate], [firstDate], and [lastDate] parameters must
/// not be null.
///
/// See also:
///
/// * [showTimePicker], which shows a dialog that contains a material design
/// time picker.
/// * [DayPicker], which displays the days of a given month and allows
/// choosing a day.
/// * [MonthPicker], which displays a scrollable list of months to allow
/// picking a month.
/// * [YearPicker], which displays a scrollable list of years to allow picking
/// a year.
///
Future<DateTime?> showRoundedDatePicker(
{required BuildContext context,
double? height,
DateTime? initialDate,
DateTime? firstDate,
DateTime? lastDate,
SelectableDayPredicate? selectableDayPredicate,
DatePickerMode initialDatePickerMode = DatePickerMode.day,
Locale? locale,
TextDirection? textDirection,
ThemeData? theme,
double borderRadius = 16,
EraMode era = EraMode.CHRIST_YEAR,
ImageProvider? imageHeader,
String description = "",
String? fontFamily,
bool barrierDismissible = false,
Color background = Colors.transparent,
String? textNegativeButton,
String? textPositiveButton,
String? textActionButton,
VoidCallback? onTapActionButton,
MaterialRoundedDatePickerStyle? styleDatePicker,
MaterialRoundedYearPickerStyle? styleYearPicker,
List<String>? customWeekDays,
BuilderDayOfDatePicker? builderDay,
List<DateTime>? listDateDisabled,
OnTapDay? onTapDay,
Function? onMonthChange}) async {
initialDate ??= DateTime.now();
firstDate ??= DateTime(initialDate.year - 1);
lastDate ??= DateTime(initialDate.year + 1);
theme ??= ThemeData();
assert(
!initialDate.isBefore(firstDate),
'initialDate must be on or after firstDate',
);
assert(
!initialDate.isAfter(lastDate),
'initialDate must be on or before lastDate',
);
assert(
!firstDate.isAfter(lastDate),
'lastDate must be on or after firstDate',
);
assert(
selectableDayPredicate == null || selectableDayPredicate(initialDate),
'Provided initialDate must satisfy provided selectableDayPredicate',
);
assert(
(onTapActionButton != null && textActionButton != null) ||
onTapActionButton == null,
"If you provide onLeftBtn, you must provide leftBtn",
);
assert(debugCheckHasMaterialLocalizations(context));
Widget child = GestureDetector(
onTap: () {
if (!barrierDismissible) {
Navigator.pop(context);
}
},
child: Container(
color: background,
child: GestureDetector(
onTap: () {
//
},
child: FlutterRoundedDatePickerDialog(
height: height,
initialDate: initialDate,
firstDate: firstDate,
lastDate: lastDate,
selectableDayPredicate: selectableDayPredicate,
initialDatePickerMode: initialDatePickerMode,
era: era,
locale: locale,
borderRadius: borderRadius,
imageHeader: imageHeader,
description: description,
fontFamily: fontFamily,
textNegativeButton: textNegativeButton,
textPositiveButton: textPositiveButton,
textActionButton: textActionButton,
onTapActionButton: onTapActionButton,
styleDatePicker: styleDatePicker,
styleYearPicker: styleYearPicker,
customWeekDays: customWeekDays,
builderDay: builderDay,
listDateDisabled: listDateDisabled,
onTapDay: onTapDay,
onMonthChange: onMonthChange,
),
),
),
);
if (textDirection != null) {
child = Directionality(
textDirection: textDirection,
child: child,
);
}
if (locale != null) {
child = Localizations.override(
context: context,
locale: locale,
child: child,
);
}
return await showDialog<DateTime>(
context: context,
barrierDismissible: barrierDismissible,
builder: (_) => Theme(data: theme!, child: child),
);
}