diff --git a/README.md b/README.md
index a1ec939..759d267 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,10 @@ Flutter Date Picker Library that provides a calendar as a horizontal timeline.
+
+
+
+
## How To Use
Import the following package in your dart file
@@ -31,6 +35,7 @@ Column(
initialSelectedDate: DateTime.now(),
selectionColor: Colors.black,
selectedTextColor: Colors.white,
+ // timelineType: TimelineType.MONTH,
onDateChange: (date) {
// New date selected
setState(() {
@@ -45,8 +50,7 @@ Column(
##### Constructor:
```dart
-DatePicker(
- this.startDate, {
+DatePicker(this.startDate, {
Key key,
this.width = 60,
this.height = 80,
@@ -54,13 +58,15 @@ DatePicker(
this.monthTextStyle = defaultMonthTextStyle,
this.dayTextStyle = defaultDayTextStyle,
this.dateTextStyle = defaultDateTextStyle,
+ this.yearTextStyle = defaultYearTextStyle,
this.selectedTextColor = Colors.white,
this.selectionColor = AppColors.defaultSelectionColor,
this.initialSelectedDate,
this.daysCount = 500,
this.onDateChange,
this.locale = "en_US",
-}) : super(key: key);
+ this.timelineType = TimelineType.DAY
+ }) : super(key: key);
```
Author
diff --git a/example/lib/main.dart b/example/lib/main.dart
index b35e193..64b7608 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -70,6 +70,7 @@ class _MyHomePageState extends State {
initialSelectedDate: DateTime.now(),
selectionColor: Colors.black,
selectedTextColor: Colors.white,
+// timelineType: TimelineType.MONTH,
onDateChange: (date) {
// New date selected
setState(() {
diff --git a/lib/date_picker_timeline.dart b/lib/date_picker_timeline.dart
index dea4fb8..281af9e 100644
--- a/lib/date_picker_timeline.dart
+++ b/lib/date_picker_timeline.dart
@@ -1,3 +1,4 @@
library date_picker_timeline;
export 'date_picker_widget.dart';
+export 'timelineType.dart';
diff --git a/lib/date_picker_widget.dart b/lib/date_picker_widget.dart
index b6de39a..26ce6e3 100644
--- a/lib/date_picker_widget.dart
+++ b/lib/date_picker_widget.dart
@@ -2,6 +2,8 @@ import 'package:date_picker_timeline/date_widget.dart';
import 'package:date_picker_timeline/extra/color.dart';
import 'package:date_picker_timeline/extra/style.dart';
import 'package:date_picker_timeline/gestures/tap.dart';
+import 'package:date_picker_timeline/month_widget.dart';
+import 'package:date_picker_timeline/timelineType.dart';
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';
@@ -34,6 +36,9 @@ class DatePicker extends StatefulWidget {
/// TextStyle for the date Value
final TextStyle dateTextStyle;
+ /// TextStyle for the year Value
+ final TextStyle yearTextStyle;
+
/// Current Selected Date
final DateTime initialSelectedDate;
@@ -47,8 +52,12 @@ class DatePicker extends StatefulWidget {
/// Locale for the calendar default: en_us
final String locale;
- DatePicker(
- this.startDate, {
+ /// Setting the TimelineType
+ /// TimelineType.DAY & TimelineType.MONTH
+ /// Default is TimelineType.DAY
+ final TimelineType timelineType;
+
+ DatePicker(this.startDate, {
Key key,
this.width = 60,
this.height = 80,
@@ -56,12 +65,14 @@ class DatePicker extends StatefulWidget {
this.monthTextStyle = defaultMonthTextStyle,
this.dayTextStyle = defaultDayTextStyle,
this.dateTextStyle = defaultDateTextStyle,
+ this.yearTextStyle = defaultYearTextStyle,
this.selectedTextColor = Colors.white,
this.selectionColor = AppColors.defaultSelectionColor,
this.initialSelectedDate,
this.daysCount = 500,
this.onDateChange,
this.locale = "en_US",
+ this.timelineType = TimelineType.DAY
}) : super(key: key);
@override
@@ -76,10 +87,16 @@ class _DatePickerState extends State {
TextStyle selectedDateStyle;
TextStyle selectedMonthStyle;
TextStyle selectedDayStyle;
+ TextStyle selectedYearStyle;
+ //For Creation of month data
+ DateTime _monthStartDate;
+ int _monthDayCount;
+ List monthList;
+ //
@override
void initState() {
- // Init the calendar locale
+ monthList = new List();
initializeDateFormatting(widget.locale, null);
// Set initial Values
_currentDate = widget.initialSelectedDate;
@@ -91,7 +108,11 @@ class _DatePickerState extends State {
this.selectedDateStyle = createTextStyle(widget.dateTextStyle);
this.selectedMonthStyle = createTextStyle(widget.monthTextStyle);
this.selectedDayStyle = createTextStyle(widget.dayTextStyle);
-
+ this.selectedYearStyle = createTextStyle(widget.yearTextStyle);
+ WidgetsBinding.instance.addPostFrameCallback((_) async {
+ //Creating month data
+ await monthDataCreation();
+ });
super.initState();
}
@@ -111,9 +132,23 @@ class _DatePickerState extends State {
}
}
+ ///Creating month data on basis of daysCount parameter passed
+ ///Selected month will give First Day of the month on selected.
+ monthDataCreation() async {
+ _monthStartDate = widget.startDate;
+ _monthDayCount = 0;
+ setState(() {
+ while (_monthDayCount < widget.daysCount) {
+ monthList.add(DateTime(_monthStartDate.year, _monthStartDate.month, 01));
+ _monthStartDate = _monthStartDate.add(Duration(days: 31));
+ _monthDayCount++;
+ }
+ });
+ }
+
@override
Widget build(BuildContext context) {
- return Container(
+ return widget.timelineType == TimelineType.DAY ? Container(
height: widget.height,
child: ListView.builder(
itemCount: widget.daysCount,
@@ -123,24 +158,57 @@ class _DatePickerState extends State {
// get the date object based on the index position
// if widget.startDate is null then use the initialDateValue
DateTime date;
- DateTime _date = widget.startDate.add(Duration(days: index));
- date = new DateTime(_date.year, _date.month, _date.day);
+ bool isSelected = false;
- // Check if this date is the one that is currently selected
- bool isSelected = _currentDate != null? _compareDate(date, _currentDate) : false;
+ if (widget.timelineType == TimelineType.DAY) {
+ DateTime _date = widget.startDate.add(Duration(days: index));
+ date = new DateTime(_date.year, _date.month, _date.day);
+ // Check if this date is the one that is currently selected
+ isSelected = _compareDate(date, _currentDate);
+ }
// Return the Date Widget
return DateWidget(
date: date,
monthTextStyle:
- isSelected ? selectedMonthStyle : widget.monthTextStyle,
+ isSelected ? selectedMonthStyle : widget.monthTextStyle,
dateTextStyle:
- isSelected ? selectedDateStyle : widget.dateTextStyle,
+ isSelected ? selectedDateStyle : widget.dateTextStyle,
dayTextStyle: isSelected ? selectedDayStyle : widget.dayTextStyle,
width: widget.width,
locale: widget.locale,
selectionColor:
- isSelected ? widget.selectionColor : Colors.transparent,
+ isSelected ? widget.selectionColor : Colors.transparent,
+ onDateSelected: (selectedDate) {
+ // A date is selected
+ if (widget.onDateChange != null) {
+ widget.onDateChange(selectedDate);
+ }
+ setState(() {
+ _currentDate = selectedDate;
+ });
+ },
+ );
+ },
+ ),
+ ) : Container(
+ height: widget.height,
+ child: ListView.builder(
+ itemCount: monthList.length,
+ scrollDirection: Axis.horizontal,
+ controller: _controller,
+ itemBuilder: (context, index) {
+ bool isSelected = _compareMonth(monthList[index], _currentDate);
+ // Return the Date Widget
+ return MonthWidget(
+ date: monthList[index],
+ monthTextStyle:
+ isSelected ? selectedMonthStyle : widget.monthTextStyle,
+ yearTextStyle: isSelected ? selectedYearStyle : widget.yearTextStyle,
+ width: widget.width,
+ locale: widget.locale,
+ selectionColor:
+ isSelected ? widget.selectionColor : Colors.transparent,
onDateSelected: (selectedDate) {
// A date is selected
if (widget.onDateChange != null) {
@@ -163,6 +231,12 @@ class _DatePickerState extends State {
date1.month == date2.month &&
date1.year == date2.year;
}
+
+ /// Helper function to compare two dates (month & year)
+ /// Returns True if both dates(month & year) are the same
+ bool _compareMonth(DateTime date1, DateTime date2) {
+ return date1.month == date2.month && date1.year == date2.year;
+ }
}
class DatePickerController {
@@ -174,7 +248,7 @@ class DatePickerController {
void jumpToSelection() {
assert(_datePickerState != null,
- 'DatePickerController is not attached to any DatePicker View.');
+ 'DatePickerController is not attached to any DatePicker View.');
// jump to the current Date
_datePickerState._controller
@@ -185,7 +259,7 @@ class DatePickerController {
void animateToSelection(
{duration = const Duration(milliseconds: 500), curve = Curves.linear}) {
assert(_datePickerState != null,
- 'DatePickerController is not attached to any DatePicker View.');
+ 'DatePickerController is not attached to any DatePicker View.');
// animate to the current date
_datePickerState._controller.animateTo(
@@ -199,7 +273,7 @@ class DatePickerController {
void animateToDate(DateTime date,
{duration = const Duration(milliseconds: 500), curve = Curves.linear}) {
assert(_datePickerState != null,
- 'DatePickerController is not attached to any DatePicker View.');
+ 'DatePickerController is not attached to any DatePicker View.');
_datePickerState._controller.animateTo(_calculateDateOffset(date),
duration: duration, curve: curve);
@@ -208,7 +282,9 @@ class DatePickerController {
/// Calculate the number of pixels that needs to be scrolled to go to the
/// date provided in the argument
double _calculateDateOffset(DateTime date) {
- int offset = date.difference(_datePickerState.widget.startDate).inDays + 1;
+ int offset = date
+ .difference(_datePickerState.widget.startDate)
+ .inDays + 1;
return (offset * _datePickerState.widget.width) + (offset * 6);
}
}
diff --git a/lib/extra/dimen.dart b/lib/extra/dimen.dart
index a5d3179..d86e8b3 100644
--- a/lib/extra/dimen.dart
+++ b/lib/extra/dimen.dart
@@ -11,4 +11,5 @@ class Dimen {
static const double dateTextSize = 24;
static const double dayTextSize = 11;
static const double monthTextSize = 11;
+ static const double yearTextSize = 15;
}
diff --git a/lib/extra/style.dart b/lib/extra/style.dart
index a72aa53..6ad3605 100644
--- a/lib/extra/style.dart
+++ b/lib/extra/style.dart
@@ -19,3 +19,10 @@ const TextStyle defaultDayTextStyle = TextStyle(
fontSize: Dimen.dayTextSize,
fontWeight: FontWeight.w500,
);
+
+
+const TextStyle defaultYearTextStyle = TextStyle(
+ color: AppColors.defaultDayColor,
+ fontSize: Dimen.yearTextSize,
+ fontWeight: FontWeight.w500,
+);
diff --git a/lib/month_widget.dart b/lib/month_widget.dart
new file mode 100644
index 0000000..988323e
--- /dev/null
+++ b/lib/month_widget.dart
@@ -0,0 +1,58 @@
+import 'package:date_picker_timeline/gestures/tap.dart';
+import 'package:flutter/material.dart';
+import 'package:intl/intl.dart';
+
+class MonthWidget extends StatelessWidget {
+ final double width;
+ final DateTime date;
+ final TextStyle monthTextStyle,yearTextStyle;
+ final Color selectionColor;
+ final DateSelectionCallback onDateSelected;
+ final String locale;
+
+ MonthWidget(
+ {@required this.date,
+ @required this.monthTextStyle,
+ @required this.yearTextStyle,
+ @required this.selectionColor,
+ this.width,
+ this.onDateSelected,
+ this.locale,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return InkWell(
+ child: Container(
+ width: width,
+ margin: EdgeInsets.all(3.0),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(8.0)),
+ color: selectionColor,
+ ),
+ child: Padding(
+ padding: EdgeInsets.all(8),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Expanded(
+ child: Text(new DateFormat("yyyy", locale).format(date).toUpperCase(), // Month
+ style: yearTextStyle),
+ ),
+ Text(new DateFormat("MMM", locale).format(date).toUpperCase(), // Month
+ style: monthTextStyle),
+ ],
+ ),
+ ),
+ ),
+ onTap: () {
+ // Check if onDateSelected is not null
+ if (onDateSelected != null) {
+ // Call the onDateSelected Function
+ onDateSelected(this.date);
+ }
+ },
+ );
+ }
+}
diff --git a/lib/timelineType.dart b/lib/timelineType.dart
new file mode 100644
index 0000000..167305a
--- /dev/null
+++ b/lib/timelineType.dart
@@ -0,0 +1 @@
+enum TimelineType { DAY, MONTH }
\ No newline at end of file
diff --git a/screenshots/monthDatePicker.png b/screenshots/monthDatePicker.png
new file mode 100644
index 0000000..089eb6b
Binary files /dev/null and b/screenshots/monthDatePicker.png differ