1
0
mirror of https://github.com/nisrulz/flutter-examples.git synced 2026-09-01 12:40:43 +00:00

New Example - Calendar (#91)

This commit is contained in:
Ishaan Kesarwani
2022-10-22 23:59:43 +05:30
committed by GitHub
parent d9cc97a7ea
commit 91d4d1b868
100 changed files with 7300 additions and 0 deletions

View File

@@ -0,0 +1,386 @@
import 'package:flutter/material.dart';
import 'range_picker.dart';
import 'week_picker.dart';
/// 0 points to Sunday, and 6 points to Saturday.
typedef DayHeaderStyleBuilder = DayHeaderStyle? Function(int dayOfTheWeek);
/// Common styles for date pickers.
///
/// To define more styles for date pickers which allow select some range
/// (e.g. [RangePicker], [WeekPicker]) use [DatePickerRangeStyles].
@immutable
class DatePickerStyles {
/// Styles for title of displayed period
/// (e.g. month for day picker and year for month picker).
final TextStyle? displayedPeriodTitle;
/// Style for the number of current date.
final TextStyle? currentDateStyle;
/// Style for the numbers of disabled dates.
final TextStyle? disabledDateStyle;
/// Style for the number of selected date.
final TextStyle? selectedDateStyle;
/// Used for date which is neither current nor disabled nor selected.
final TextStyle? defaultDateTextStyle;
/// Day cell decoration for selected date in case only one date is selected.
final BoxDecoration? selectedSingleDateDecoration;
/// Style for the day header.
///
/// If you need to customize day header's style depends on day of the week
/// use [dayHeaderStyleBuilder] instead.
final DayHeaderStyle? dayHeaderStyle;
/// Builder to customize styles for day headers depends on day of the week.
/// Where 0 points to Sunday and 6 points to Saturday.
///
/// Builder must return not null value for every weekday from 0 to 6.
///
/// If styles should be the same for any day of the week
/// use [dayHeaderStyle] instead.
final DayHeaderStyleBuilder? dayHeaderStyleBuilder;
/// Widget which will be shown left side of the shown page title.
/// User goes to previous data period by click on it.
final Widget prevIcon;
/// Widget which will be shown right side of the shown page title.
/// User goes to next data period by click on it.
final Widget nextIcon;
/// Index of the first day of week, where 0 points to Sunday, and 6 points to
/// Saturday. Must not be less 0 or more then 6.
///
/// Can be null. In this case value from current locale will be used.
final int? firstDayOfeWeekIndex;
/// Styles for date picker.
DatePickerStyles({
this.displayedPeriodTitle,
this.currentDateStyle,
this.disabledDateStyle,
this.selectedDateStyle,
this.selectedSingleDateDecoration,
this.defaultDateTextStyle,
this.dayHeaderStyleBuilder,
this.dayHeaderStyle,
this.firstDayOfeWeekIndex,
this.prevIcon = const Icon(Icons.chevron_left),
this.nextIcon = const Icon(Icons.chevron_right)
}) : assert(!(dayHeaderStyle != null && dayHeaderStyleBuilder != null),
"Should be only one from: dayHeaderStyleBuilder, dayHeaderStyle."),
assert(dayHeaderStyleBuilder == null
|| _validateDayHeaderStyleBuilder(dayHeaderStyleBuilder),
"dayHeaderStyleBuilder must return not null value from every weekday "
"(from 0 to 6)."),
assert(_validateFirstDayOfWeek(firstDayOfeWeekIndex),
"firstDayOfeWeekIndex must be null or in correct range (from 0 to 6).");
/// Return new [DatePickerStyles] object where fields
/// with null values set with defaults from theme.
DatePickerStyles fulfillWithTheme(ThemeData theme) {
Color accentColor = theme.accentColor;
TextStyle? _displayedPeriodTitle =
displayedPeriodTitle ?? theme.textTheme.subtitle1;
TextStyle? _currentDateStyle = currentDateStyle ??
theme.textTheme.bodyText1?.copyWith(color: theme.accentColor);
TextStyle? _disabledDateStyle = disabledDateStyle ??
theme.textTheme.bodyText2?.copyWith(color: theme.disabledColor);
TextStyle? _selectedDateStyle =
selectedDateStyle ?? theme.accentTextTheme.bodyText1;
TextStyle? _defaultDateTextStyle =
defaultDateTextStyle ?? theme.textTheme.bodyText2;
BoxDecoration _selectedSingleDateDecoration =
selectedSingleDateDecoration ??
BoxDecoration(
color: accentColor,
borderRadius: const BorderRadius.all(Radius.circular(10.0)));
DayHeaderStyle? _dayHeaderStyle = dayHeaderStyle;
if (dayHeaderStyleBuilder == null && _dayHeaderStyle == null) {
_dayHeaderStyle = DayHeaderStyle(textStyle: theme.textTheme.caption);
}
return DatePickerStyles(
disabledDateStyle: _disabledDateStyle,
currentDateStyle: _currentDateStyle,
displayedPeriodTitle: _displayedPeriodTitle,
selectedDateStyle: _selectedDateStyle,
selectedSingleDateDecoration: _selectedSingleDateDecoration,
defaultDateTextStyle: _defaultDateTextStyle,
dayHeaderStyle: _dayHeaderStyle,
dayHeaderStyleBuilder: dayHeaderStyleBuilder,
nextIcon: nextIcon,
prevIcon: prevIcon
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
return other is DatePickerStyles
&& other.displayedPeriodTitle == displayedPeriodTitle
&& other.currentDateStyle == currentDateStyle
&& other.disabledDateStyle == disabledDateStyle
&& other.selectedDateStyle == selectedDateStyle
&& other.defaultDateTextStyle == defaultDateTextStyle
&& other.selectedSingleDateDecoration == selectedSingleDateDecoration
&& other.dayHeaderStyle == dayHeaderStyle
&& other.dayHeaderStyleBuilder == dayHeaderStyleBuilder
&& other.prevIcon == prevIcon
&& other.nextIcon == nextIcon
&& other.firstDayOfeWeekIndex == firstDayOfeWeekIndex;
}
@override
int get hashCode =>
hashValues(
displayedPeriodTitle,
currentDateStyle,
disabledDateStyle,
selectedDateStyle,
defaultDateTextStyle,
selectedSingleDateDecoration,
dayHeaderStyle,
dayHeaderStyleBuilder,
prevIcon,
nextIcon,
firstDayOfeWeekIndex
);
static bool _validateDayHeaderStyleBuilder(DayHeaderStyleBuilder builder) {
List<int> weekdays = const [0, 1, 2, 3, 4, 5, 6];
// ignore: avoid_types_on_closure_parameters
bool valid = weekdays.every((int weekday) => builder(weekday) != null);
return valid;
}
static bool _validateFirstDayOfWeek(int? index) {
if (index == null) return true;
bool valid = index >= 0 && index <= 6;
return valid;
}
}
/// Styles for date pickers which allow select some range
/// (e.g. RangePicker, WeekPicker).
@immutable
class DatePickerRangeStyles extends DatePickerStyles {
/// Decoration for the first date of the selected range.
final BoxDecoration? selectedPeriodStartDecoration;
/// Text style for the first date of the selected range.
///
/// If null - default [DatePickerStyles.selectedDateStyle] will be used.
final TextStyle? selectedPeriodStartTextStyle;
/// Decoration for the last date of the selected range.
final BoxDecoration? selectedPeriodLastDecoration;
/// Text style for the last date of the selected range.
///
/// If null - default [DatePickerStyles.selectedDateStyle] will be used.
final TextStyle? selectedPeriodEndTextStyle;
/// Decoration for the date of the selected range
/// which is not first date and not end date of this range.
///
/// If there is only one date selected
/// [DatePickerStyles.selectedSingleDateDecoration] will be used.
final BoxDecoration? selectedPeriodMiddleDecoration;
/// Text style for the middle date of the selected range.
///
/// If null - default [DatePickerStyles.selectedDateStyle] will be used.
final TextStyle? selectedPeriodMiddleTextStyle;
/// Return new [DatePickerRangeStyles] object
/// where fields with null values set with defaults from given theme.
@override
DatePickerRangeStyles fulfillWithTheme(ThemeData theme) {
Color accentColor = theme.accentColor;
DatePickerStyles commonStyles = super.fulfillWithTheme(theme);
final BoxDecoration _selectedPeriodStartDecoration =
selectedPeriodStartDecoration ??
BoxDecoration(
color: accentColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10.0),
bottomLeft: Radius.circular(10.0)),
);
final BoxDecoration _selectedPeriodLastDecoration =
selectedPeriodLastDecoration ??
BoxDecoration(
color: accentColor,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)),
);
final BoxDecoration _selectedPeriodMiddleDecoration =
selectedPeriodMiddleDecoration ??
BoxDecoration(
color: accentColor,
shape: BoxShape.rectangle,
);
final TextStyle? _selectedPeriodStartTextStyle =
selectedPeriodStartTextStyle ?? commonStyles.selectedDateStyle;
final TextStyle? _selectedPeriodMiddleTextStyle =
selectedPeriodMiddleTextStyle ?? commonStyles.selectedDateStyle;
final TextStyle? _selectedPeriodEndTextStyle =
selectedPeriodEndTextStyle ?? commonStyles.selectedDateStyle;
return DatePickerRangeStyles(
disabledDateStyle: commonStyles.disabledDateStyle,
currentDateStyle: commonStyles.currentDateStyle,
displayedPeriodTitle: commonStyles.displayedPeriodTitle,
selectedDateStyle: commonStyles.selectedDateStyle,
selectedSingleDateDecoration: commonStyles.selectedSingleDateDecoration,
defaultDateTextStyle: commonStyles.defaultDateTextStyle,
dayHeaderStyle: commonStyles.dayHeaderStyle,
dayHeaderStyleBuilder: commonStyles.dayHeaderStyleBuilder,
firstDayOfWeekIndex: firstDayOfeWeekIndex,
selectedPeriodStartDecoration: _selectedPeriodStartDecoration,
selectedPeriodMiddleDecoration: _selectedPeriodMiddleDecoration,
selectedPeriodLastDecoration: _selectedPeriodLastDecoration,
selectedPeriodStartTextStyle: _selectedPeriodStartTextStyle,
selectedPeriodMiddleTextStyle: _selectedPeriodMiddleTextStyle,
selectedPeriodEndTextStyle: _selectedPeriodEndTextStyle,
);
}
/// Styles for the pickers that allows to select range ([RangePicker],
/// [WeekPicker]).
DatePickerRangeStyles({
displayedPeriodTitle,
currentDateStyle,
disabledDateStyle,
selectedDateStyle,
selectedSingleDateDecoration,
defaultDateTextStyle,
dayHeaderStyle,
dayHeaderStyleBuilder,
Widget nextIcon = const Icon(Icons.chevron_right),
Widget prevIcon = const Icon(Icons.chevron_left),
firstDayOfWeekIndex,
this.selectedPeriodLastDecoration,
this.selectedPeriodMiddleDecoration,
this.selectedPeriodStartDecoration,
this.selectedPeriodStartTextStyle,
this.selectedPeriodMiddleTextStyle,
this.selectedPeriodEndTextStyle,
}) : super(
displayedPeriodTitle: displayedPeriodTitle,
currentDateStyle: currentDateStyle,
disabledDateStyle: disabledDateStyle,
selectedDateStyle: selectedDateStyle,
selectedSingleDateDecoration: selectedSingleDateDecoration,
defaultDateTextStyle: defaultDateTextStyle,
dayHeaderStyle: dayHeaderStyle,
dayHeaderStyleBuilder: dayHeaderStyleBuilder,
nextIcon: nextIcon,
prevIcon: prevIcon,
firstDayOfeWeekIndex: firstDayOfWeekIndex
);
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
return other is DatePickerRangeStyles
&& other.selectedPeriodStartDecoration == selectedPeriodStartDecoration
&& other.selectedPeriodStartTextStyle == selectedPeriodStartTextStyle
&& other.selectedPeriodLastDecoration == selectedPeriodLastDecoration
&& other.selectedPeriodEndTextStyle == selectedPeriodEndTextStyle
&& other.selectedPeriodMiddleDecoration ==selectedPeriodMiddleDecoration
&& other.selectedPeriodMiddleTextStyle == selectedPeriodMiddleTextStyle
&& other.displayedPeriodTitle == displayedPeriodTitle
&& other.currentDateStyle == currentDateStyle
&& other.disabledDateStyle == disabledDateStyle
&& other.selectedDateStyle == selectedDateStyle
&& other.defaultDateTextStyle == defaultDateTextStyle
&& other.selectedSingleDateDecoration == selectedSingleDateDecoration
&& other.dayHeaderStyle == dayHeaderStyle
&& other.dayHeaderStyleBuilder == dayHeaderStyleBuilder
&& other.prevIcon == prevIcon
&& other.nextIcon == nextIcon
&& other.firstDayOfeWeekIndex == firstDayOfeWeekIndex;
}
@override
int get hashCode =>
hashValues(
selectedPeriodStartDecoration,
selectedPeriodStartTextStyle,
selectedPeriodLastDecoration,
selectedPeriodEndTextStyle,
selectedPeriodMiddleDecoration,
selectedPeriodMiddleTextStyle,
displayedPeriodTitle,
currentDateStyle,
disabledDateStyle,
selectedDateStyle,
defaultDateTextStyle,
selectedSingleDateDecoration,
dayHeaderStyle,
dayHeaderStyleBuilder,
prevIcon,
nextIcon,
firstDayOfeWeekIndex
);
}
/// User styles for the day header in date picker.
@immutable
class DayHeaderStyle {
/// If null - textTheme.caption from the Theme will be used.
final TextStyle? textStyle;
/// If null - no decoration will be applied for the day header;
final BoxDecoration? decoration;
/// Creates styles for the day headers in date pickers.
///
/// See also:
/// * [DatePickerStyles.dayHeaderStyleBuilder]
const DayHeaderStyle({
this.textStyle,
this.decoration
});
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
return other is DayHeaderStyle
&& other.textStyle == textStyle
&& other.decoration == decoration;
}
@override
int get hashCode => hashValues(
textStyle,
decoration
);
}