mirror of
https://github.com/Iconica-Development/flutter_date_time_picker.git
synced 2025-05-18 18:33:49 +02:00
feat: Added the feature to add the weekdays letters above the months
This commit is contained in:
parent
bd448daacc
commit
f0be7a5e36
5 changed files with 161 additions and 115 deletions
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -1,18 +1,25 @@
|
||||||
|
## 2.2.0
|
||||||
|
|
||||||
|
- Added the abilty to add the weekday letters above the months
|
||||||
|
|
||||||
## 2.1.0
|
## 2.1.0
|
||||||
* Fixed internalization of the package
|
|
||||||
* Added dragcallback to the draggablesheet
|
- Fixed internalization of the package
|
||||||
|
- Added dragcallback to the draggablesheet
|
||||||
|
|
||||||
## 2.0.0
|
## 2.0.0
|
||||||
* Added overlay variant of datetimepicker
|
|
||||||
|
- Added overlay variant of datetimepicker
|
||||||
|
|
||||||
## 1.2.0
|
## 1.2.0
|
||||||
* Made date time picker height customizable
|
|
||||||
|
- Made date time picker height customizable
|
||||||
|
|
||||||
## 1.1.0
|
## 1.1.0
|
||||||
|
|
||||||
* Added option to change background color of date picker.
|
- Added option to change background color of date picker.
|
||||||
* Added option to style the bar at the bottom of the date picker.
|
- Added option to style the bar at the bottom of the date picker.
|
||||||
|
|
||||||
## 1.0.0
|
## 1.0.0
|
||||||
|
|
||||||
* TODO: Describe initial release.
|
- TODO: Describe initial release.
|
||||||
|
|
|
@ -36,6 +36,7 @@ class DateTimePickerTheme {
|
||||||
TextStyle(color: Colors.white),
|
TextStyle(color: Colors.white),
|
||||||
),
|
),
|
||||||
this.barTheme = const DateTimePickerBarTheme(),
|
this.barTheme = const DateTimePickerBarTheme(),
|
||||||
|
this.monthWeekDayHeaders = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// enum to define a shape dor the date. use [DateBoxShape.circle].
|
/// enum to define a shape dor the date. use [DateBoxShape.circle].
|
||||||
|
@ -83,4 +84,7 @@ class DateTimePickerTheme {
|
||||||
|
|
||||||
/// The shape of the border using a [ShapeBorder]
|
/// The shape of the border using a [ShapeBorder]
|
||||||
final ShapeBorder? shapeBorder;
|
final ShapeBorder? shapeBorder;
|
||||||
|
|
||||||
|
/// If true the first letters of the weekdays will be displayed above the days of the month
|
||||||
|
final bool monthWeekDayHeaders;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import 'package:flutter_date_time_picker/src/extensions/time_of_day.dart';
|
||||||
import 'package:flutter_date_time_picker/src/models/date_box_current_theme.dart';
|
import 'package:flutter_date_time_picker/src/models/date_box_current_theme.dart';
|
||||||
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
|
import 'package:flutter_date_time_picker/src/models/date_time_picker_theme.dart';
|
||||||
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
|
import 'package:flutter_date_time_picker/src/utils/date_time_picker_controller.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class MonthDateTimePicker extends StatelessWidget {
|
class MonthDateTimePicker extends StatelessWidget {
|
||||||
const MonthDateTimePicker({
|
const MonthDateTimePicker({
|
||||||
|
@ -35,115 +36,146 @@ class MonthDateTimePicker extends StatelessWidget {
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 30),
|
margin: const EdgeInsets.symmetric(horizontal: 30),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: GridView.count(
|
child: Column(
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
children: [
|
||||||
crossAxisSpacing: 5,
|
if (dateTimePickerController.theme.monthWeekDayHeaders)
|
||||||
crossAxisCount: 7,
|
Row(
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
DateTime(date.year, date.month).daysInMonth() +
|
7,
|
||||||
(daysToSkip >= 7 ? 0 : daysToSkip),
|
(index) => Expanded(
|
||||||
(index) {
|
child: Center(
|
||||||
late DateBoxCurrentTheme currentDateBoxTheme;
|
child: Text(
|
||||||
|
DateFormat.E(Localizations.localeOf(context).toString())
|
||||||
int addedIndex = index;
|
.format(
|
||||||
|
date.daysOfWeek().elementAt(index),
|
||||||
if (daysToSkip >= 7) {
|
)
|
||||||
addedIndex = index + 7;
|
.toUpperCase()[0],
|
||||||
}
|
style:
|
||||||
if (addedIndex < daysToSkip) {
|
dateTimePickerController.theme.baseTheme.textStyle,
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
|
||||||
|
|
||||||
currentDateBoxTheme = determineCurrentDateBoxTheme(context,
|
|
||||||
addedIndex, daysToSkip, dateTimePickerController.theme);
|
|
||||||
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: isDisabled(
|
|
||||||
addedIndex,
|
|
||||||
daysToSkip,
|
|
||||||
)
|
|
||||||
? null
|
|
||||||
: () async {
|
|
||||||
TimeOfDay? timeOfDay;
|
|
||||||
|
|
||||||
DateTime selectedDate = DateTime(
|
|
||||||
date.year,
|
|
||||||
date.month,
|
|
||||||
addedIndex + 1 - daysToSkip,
|
|
||||||
);
|
|
||||||
|
|
||||||
timeOfDay = const TimeOfDay(hour: 0, minute: 0);
|
|
||||||
|
|
||||||
if (dateTimePickerController.pickTime) {
|
|
||||||
timeOfDay = await displayTimePicker(
|
|
||||||
context, dateTimePickerController);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dateTimePickerController.wrongTimeDialog != null) {
|
|
||||||
if (timeOfDay != null &&
|
|
||||||
timeOfDay.containsAny(
|
|
||||||
dateTimePickerController.disabledTimes ?? [],
|
|
||||||
)) {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) =>
|
|
||||||
dateTimePickerController.wrongTimeDialog!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DateTime selectedDateTime = DateTime(
|
|
||||||
selectedDate.year,
|
|
||||||
selectedDate.month,
|
|
||||||
selectedDate.day,
|
|
||||||
timeOfDay!.hour,
|
|
||||||
timeOfDay.minute,
|
|
||||||
);
|
|
||||||
|
|
||||||
dateTimePickerController.onTapDay(selectedDateTime);
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
margin:
|
|
||||||
const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: currentDateBoxTheme.backgroundColor,
|
|
||||||
borderRadius:
|
|
||||||
_determineBorderRadius(dateTimePickerController),
|
|
||||||
),
|
|
||||||
height: monthDateBoxSize,
|
|
||||||
width: monthDateBoxSize,
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
Center(
|
|
||||||
child: Text((addedIndex + 1 - daysToSkip).toString(),
|
|
||||||
style: currentDateBoxTheme.textStyle),
|
|
||||||
),
|
),
|
||||||
if (shouldMark(
|
),
|
||||||
addedIndex,
|
|
||||||
daysToSkip,
|
|
||||||
)) ...[
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.bottomRight,
|
|
||||||
child: IgnorePointer(
|
|
||||||
child: Container(
|
|
||||||
width: monthDateBoxSize / 4,
|
|
||||||
height: monthDateBoxSize / 4,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: dateTimePickerController
|
|
||||||
.theme.markedIndicatorColor ??
|
|
||||||
Theme.of(context).indicatorColor,
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
(monthDateBoxSize / 4) * 2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
SizedBox(
|
||||||
),
|
height: MediaQuery.of(context).size.height * 0.33,
|
||||||
|
child: GridView.count(
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
crossAxisSpacing: 5,
|
||||||
|
crossAxisCount: 7,
|
||||||
|
children: List.generate(
|
||||||
|
DateTime(date.year, date.month).daysInMonth() +
|
||||||
|
(daysToSkip >= 7 ? 0 : daysToSkip),
|
||||||
|
(index) {
|
||||||
|
late DateBoxCurrentTheme currentDateBoxTheme;
|
||||||
|
|
||||||
|
int addedIndex = index;
|
||||||
|
|
||||||
|
if (daysToSkip >= 7) {
|
||||||
|
addedIndex = index + 7;
|
||||||
|
}
|
||||||
|
if (addedIndex < daysToSkip) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDateBoxTheme = determineCurrentDateBoxTheme(context,
|
||||||
|
addedIndex, daysToSkip, dateTimePickerController.theme);
|
||||||
|
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: isDisabled(
|
||||||
|
addedIndex,
|
||||||
|
daysToSkip,
|
||||||
|
)
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
TimeOfDay? timeOfDay;
|
||||||
|
|
||||||
|
DateTime selectedDate = DateTime(
|
||||||
|
date.year,
|
||||||
|
date.month,
|
||||||
|
addedIndex + 1 - daysToSkip,
|
||||||
|
);
|
||||||
|
|
||||||
|
timeOfDay = const TimeOfDay(hour: 0, minute: 0);
|
||||||
|
|
||||||
|
if (dateTimePickerController.pickTime) {
|
||||||
|
timeOfDay = await displayTimePicker(
|
||||||
|
context, dateTimePickerController);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dateTimePickerController.wrongTimeDialog !=
|
||||||
|
null) {
|
||||||
|
if (timeOfDay != null &&
|
||||||
|
timeOfDay.containsAny(
|
||||||
|
dateTimePickerController.disabledTimes ??
|
||||||
|
[],
|
||||||
|
)) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) =>
|
||||||
|
dateTimePickerController
|
||||||
|
.wrongTimeDialog!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime selectedDateTime = DateTime(
|
||||||
|
selectedDate.year,
|
||||||
|
selectedDate.month,
|
||||||
|
selectedDate.day,
|
||||||
|
timeOfDay!.hour,
|
||||||
|
timeOfDay.minute,
|
||||||
|
);
|
||||||
|
|
||||||
|
dateTimePickerController
|
||||||
|
.onTapDay(selectedDateTime);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.symmetric(
|
||||||
|
vertical: 5, horizontal: 5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: currentDateBoxTheme.backgroundColor,
|
||||||
|
borderRadius:
|
||||||
|
_determineBorderRadius(dateTimePickerController),
|
||||||
|
),
|
||||||
|
height: monthDateBoxSize,
|
||||||
|
width: monthDateBoxSize,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
(addedIndex + 1 - daysToSkip).toString(),
|
||||||
|
style: currentDateBoxTheme.textStyle),
|
||||||
|
),
|
||||||
|
if (shouldMark(
|
||||||
|
addedIndex,
|
||||||
|
daysToSkip,
|
||||||
|
)) ...[
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.bottomRight,
|
||||||
|
child: IgnorePointer(
|
||||||
|
child: Container(
|
||||||
|
width: monthDateBoxSize / 4,
|
||||||
|
height: monthDateBoxSize / 4,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: dateTimePickerController
|
||||||
|
.theme.markedIndicatorColor ??
|
||||||
|
Theme.of(context).indicatorColor,
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
(monthDateBoxSize / 4) * 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -41,7 +41,10 @@ class MonthDateTimePickerSheet extends StatelessWidget {
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: MediaQuery.of(context).size.height * 0.33,
|
height: MediaQuery.of(context).size.height * 0.33 +
|
||||||
|
((theme.monthWeekDayHeaders)
|
||||||
|
? MediaQuery.of(context).size.height * 0.04
|
||||||
|
: 0),
|
||||||
child: PageView(
|
child: PageView(
|
||||||
controller: dateTimePickerController.pageController,
|
controller: dateTimePickerController.pageController,
|
||||||
onPageChanged: (i) {
|
onPageChanged: (i) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_date_time_picker
|
name: flutter_date_time_picker
|
||||||
description: A Flutter package for date and time picker.
|
description: A Flutter package for date and time picker.
|
||||||
version: 2.1.0
|
version: 2.2.0
|
||||||
homepage: https://iconica.nl/
|
homepage: https://iconica.nl/
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
Loading…
Reference in a new issue