Skip to content

Commit 6ee3819

Browse files
authored
Merge pull request #153 from koukibadr/feat#147-create-year-picker
feat #147: create year picker
2 parents 5e8c268 + fa8f99d commit 6ee3819

9 files changed

Lines changed: 198 additions & 31 deletions

File tree

example/lib/main.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ class ExampleApp extends StatelessWidget {
100100
),
101101
),
102102
),
103+
SizedBox(
104+
width: buttonWidth,
105+
child: ElevatedButton(
106+
onPressed: () {
107+
_openYearDatePicker(context);
108+
},
109+
child: Text('Year Picker', textAlign: TextAlign.center),
110+
),
111+
),
103112
SizedBox(
104113
width: buttonWidth,
105114
child: ElevatedButton(
@@ -311,6 +320,39 @@ class ExampleApp extends StatelessWidget {
311320
).show(context);
312321
}
313322

323+
void _openYearDatePicker(BuildContext context) {
324+
BottomPicker.year(
325+
headerBuilder: (context) {
326+
return Row(
327+
children: [
328+
Text(
329+
'Set your Birthday Year',
330+
style: TextStyle(
331+
fontWeight: FontWeight.bold,
332+
fontSize: 15,
333+
color: Colors.blue,
334+
),
335+
),
336+
],
337+
);
338+
},
339+
initialDateTime: DateTime(1996),
340+
maxDateTime: DateTime(1998),
341+
minDateTime: DateTime(1980),
342+
onChange: (index) {
343+
print(index);
344+
},
345+
onSubmit: (index) {
346+
print(index);
347+
Navigator.pop(context);
348+
},
349+
onDismiss: (p0) {
350+
print(p0);
351+
},
352+
bottomPickerTheme: BottomPickerTheme.plumPlate,
353+
).show(context);
354+
}
355+
314356
void _openMonthYearPicker(BuildContext context) {
315357
BottomPicker.monthYear(
316358
headerBuilder: (context) {

lib/bottom_picker.dart

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:bottom_picker/widgets/date_picker.dart';
1010
import 'package:bottom_picker/widgets/range_picker.dart';
1111
import 'package:bottom_picker/widgets/simple_picker.dart';
1212
import 'package:bottom_picker/widgets/time_picker.dart';
13+
import 'package:bottom_picker/widgets/year_picker.dart';
1314
import 'package:flutter/cupertino.dart';
1415
import 'package:flutter/foundation.dart';
1516
import 'package:flutter/material.dart';
@@ -139,6 +140,39 @@ class BottomPicker extends StatefulWidget {
139140
assertInitialValues();
140141
}
141142

143+
/// Creates a bottom picker for selecting a year.
144+
BottomPicker.year({
145+
super.key,
146+
this.dismissable = false,
147+
this.onChange,
148+
this.onSubmit,
149+
this.onDismiss,
150+
this.bottomPickerTheme = BottomPickerTheme.blue,
151+
this.gradientColors,
152+
this.initialDateTime,
153+
this.minDateTime,
154+
this.maxDateTime,
155+
this.buttonPadding,
156+
this.buttonWidth,
157+
this.buttonSingleColor,
158+
this.backgroundColor = Colors.white,
159+
this.pickerThemeData,
160+
this.buttonAlignment = MainAxisAlignment.center,
161+
this.height,
162+
this.displaySubmitButton = true,
163+
this.buttonContent,
164+
this.buttonStyle,
165+
this.itemExtent = 35.0,
166+
this.headerBuilder,
167+
}) {
168+
datePickerMode = CupertinoDatePickerMode.date;
169+
bottomPickerType = BottomPickerType.year;
170+
use24hFormat = false;
171+
onRangeDateSubmitPressed = null;
172+
displayCloseIcon = false;
173+
assertInitialValues();
174+
}
175+
142176
BottomPicker.monthYear({
143177
super.key,
144178
@Deprecated('should use headerBuilder instead') this.pickerTitle,
@@ -487,21 +521,21 @@ class BottomPicker extends StatefulWidget {
487521
}
488522

489523
/// Bottom picker title widget
490-
final Widget? pickerTitle;
524+
Widget? pickerTitle;
491525

492526
/// Renders the header component of the bottom picker
493527
final Widget Function(BuildContext context)? headerBuilder;
494528

495529
///Bottom picker description widget
496-
final Widget? pickerDescription;
530+
Widget? pickerDescription;
497531

498532
///The padding applied on the title
499533
///by default it is set with zero values
500-
final EdgeInsetsGeometry titlePadding;
534+
EdgeInsetsGeometry? titlePadding;
501535

502536
///Title widget alignment inside the stack
503537
///by default the title will be aligned left/right depends on `layoutOrientation`
504-
final Alignment? titleAlignment;
538+
Alignment? titleAlignment;
505539

506540
///defines whether the bottom picker is dismissable or not
507541
///by default it's set to false
@@ -532,7 +566,7 @@ class BottomPicker extends StatefulWidget {
532566

533567
///Invoked when clicking on the close button
534568
///
535-
final Function? onCloseButtonPressed;
569+
Function? onCloseButtonPressed;
536570

537571
///set the theme of the bottom picker (the button theme)
538572
///possible values
@@ -617,11 +651,11 @@ class BottomPicker extends StatefulWidget {
617651

618652
///date order applied on date picker or date time picker
619653
///by default it's YYYY/MM/DD
620-
late DatePickerDateOrder? dateOrder;
654+
DatePickerDateOrder? dateOrder;
621655

622656
///the picker text style applied on all types of bottom picker
623657
///by default `TextStyle(fontSize: 14)`
624-
final TextStyle pickerTextStyle;
658+
TextStyle? pickerTextStyle;
625659

626660
/// The picker theme data
627661
final CupertinoTextThemeData? pickerThemeData;
@@ -632,29 +666,29 @@ class BottomPicker extends StatefulWidget {
632666

633667
///indicate whether the close icon will be rendred or not
634668
/// by default `displayCloseIcon = true`
635-
final bool displayCloseIcon;
669+
bool? displayCloseIcon;
636670

637671
/// Renders the close widget if it's null and [displayCloseIcon] is true
638672
/// the default close icon is rendered.
639673
/// Note if closeWidget is provided onClosePressed won't be triggered
640674
/// since you need to handle all actions on the provided widget.
641-
final Widget? closeWidget;
675+
Widget? closeWidget;
642676

643677
///the close icon color
644678
///by default `closeIconColor = Colors.black`
645-
final Color closeIconColor;
679+
Color? closeIconColor;
646680

647681
///the close icon size
648682
///by default `closeIconSize = 20`
649-
final double closeIconSize;
683+
double? closeIconSize;
650684

651685
///the layout orientation of the bottom picker
652686
///by default the orientation is set to LTR
653687
///```
654688
///LAYOUT_ORIENTATION.ltr,
655689
///LAYOUT_ORIENTATION.rtl
656690
///```
657-
final TextDirection layoutOrientation;
691+
TextDirection? layoutOrientation;
658692

659693
///THe alignment of the bottom picker button
660694
///by default it's `MainAxisAlignment.center`
@@ -760,10 +794,10 @@ class BottomPicker extends StatefulWidget {
760794
/// when the submit button is pressed.
761795
///
762796
/// By default closeOnSubmit = true.
763-
final bool closeOnSubmit;
797+
bool? closeOnSubmit;
764798

765799
/// The datepicker calendar type
766-
final List<int> calendarDays;
800+
List<int> calendarDays = CupertinoDatePickerWidget.fullWeek;
767801

768802
///display the bottom picker popup
769803
///[context] the app context to display the popup
@@ -873,13 +907,13 @@ class BottomPickerState extends State<BottomPicker> {
873907
horizontal: 20,
874908
),
875909
child: Directionality(
876-
textDirection: widget.layoutOrientation,
910+
textDirection: widget.layoutOrientation ?? TextDirection.ltr,
877911
child: Column(
878912
mainAxisAlignment: MainAxisAlignment.start,
879913
children: [
880914
Padding(
881915
padding: widget.headerBuilder == null
882-
? widget.titlePadding
916+
? widget.titlePadding ?? const EdgeInsets.all(0)
883917
: EdgeInsetsGeometry.zero,
884918
child: Row(
885919
children: [
@@ -893,7 +927,7 @@ class BottomPickerState extends State<BottomPicker> {
893927
widget.pickerTitle != null)
894928
Expanded(child: widget.pickerTitle!),
895929
if (widget.headerBuilder == null &&
896-
widget.displayCloseIcon)
930+
(widget.displayCloseIcon ?? true))
897931
widget.closeWidget ??
898932
CloseIcon(
899933
onPress: _closeBottomPicker,
@@ -974,8 +1008,20 @@ class BottomPickerState extends State<BottomPicker> {
9741008
showTimeSeparator: widget.showTimeSeparator,
9751009
pickerThemeData: widget.pickerThemeData,
9761010
)
977-
: widget.bottomPickerType ==
978-
BottomPickerType.rangeTime
1011+
: widget.bottomPickerType == BottomPickerType.year
1012+
? BottomYearDatePicker(
1013+
initialDateTime: widget.initialDateTime,
1014+
maxDateTime: widget.maxDateTime,
1015+
minDateTime: widget.minDateTime,
1016+
onDateChanged: (DateTime date) {
1017+
selectedDateTime = date;
1018+
widget.onChange?.call(date);
1019+
},
1020+
itemExtent: widget.itemExtent,
1021+
pickerThemeData: widget.pickerThemeData,
1022+
)
1023+
: widget.bottomPickerType ==
1024+
BottomPickerType.rangeTime
9791025
? RangePicker(
9801026
mode: CupertinoDatePickerMode.time,
9811027
use24hFormat: widget.use24hFormat,
@@ -1050,7 +1096,8 @@ class BottomPickerState extends State<BottomPicker> {
10501096
);
10511097
} else if (widget.bottomPickerType ==
10521098
BottomPickerType.dateTime ||
1053-
widget.bottomPickerType == BottomPickerType.time) {
1099+
widget.bottomPickerType == BottomPickerType.time ||
1100+
widget.bottomPickerType == BottomPickerType.year) {
10541101
widget.onSubmit?.call(selectedDateTime);
10551102
} else if (widget.bottomPickerType ==
10561103
BottomPickerType.timer) {
@@ -1059,7 +1106,7 @@ class BottomPickerState extends State<BottomPicker> {
10591106
widget.onSubmit?.call(selectedItemIndex);
10601107
}
10611108

1062-
if (widget.closeOnSubmit) {
1109+
if (widget.closeOnSubmit ?? false) {
10631110
Navigator.pop(context);
10641111
}
10651112
},

lib/resources/arrays.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ enum BottomPickerType {
55
time,
66
timer,
77
dateTime,
8+
year,
89
rangeDate,
910
rangeTime,
1011
}

lib/widgets/close_icon.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
22

33
class CloseIcon extends StatelessWidget {
44
final Function() onPress;
5-
final Color iconColor;
6-
final double closeIconSize;
5+
final Color? iconColor;
6+
final double? closeIconSize;
77

88
const CloseIcon({
99
super.key,

lib/widgets/date_picker.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class DatePicker extends StatelessWidget {
1010
final int minuteInterval;
1111
final bool use24hFormat;
1212
final DatePickerDateOrder? dateOrder;
13-
final TextStyle textStyle;
13+
final TextStyle? textStyle;
1414
final double? itemExtent;
1515
final bool showTimeSeparator;
1616
final List<int> calendarDays;

lib/widgets/range_picker.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class RangePicker extends StatefulWidget {
1111
final DateTime? minFirstDateTime;
1212
final DateTime? minSecondDateTime;
1313
final DatePickerDateOrder? dateOrder;
14-
final TextStyle textStyle;
14+
final TextStyle? textStyle;
1515
final CupertinoDatePickerMode mode;
1616
final bool use24hFormat;
1717
final int? minuteInterval;

lib/widgets/simple_picker.dart

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class SimplePicker extends StatelessWidget {
77
final int selectedItemIndex;
88
final Function(int)? onChange;
99
final List<Widget> items;
10-
final TextStyle textStyle;
10+
final TextStyle? textStyle;
1111
final double itemExtent;
1212
final Widget? selectionOverlay;
1313
final CupertinoTextThemeData? pickerThemeData;
@@ -17,7 +17,7 @@ class SimplePicker extends StatelessWidget {
1717
required this.items,
1818
required this.onChange,
1919
required this.selectedItemIndex,
20-
required this.textStyle,
20+
this.textStyle,
2121
required this.itemExtent,
2222
this.selectionOverlay,
2323
this.pickerThemeData,
@@ -28,9 +28,10 @@ class SimplePicker extends StatelessWidget {
2828
if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) {
2929
return CupertinoTheme(
3030
data: CupertinoThemeData(
31-
textTheme: pickerThemeData ?? CupertinoTextThemeData(
32-
pickerTextStyle: textStyle,
33-
),
31+
textTheme: pickerThemeData ??
32+
CupertinoTextThemeData(
33+
pickerTextStyle: textStyle,
34+
),
3435
),
3536
child: CupertinoPicker(
3637
offAxisFraction: 2.0,

lib/widgets/time_picker.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
44
class TimePicker extends StatelessWidget {
55
final CupertinoTimerPickerMode mode;
66
final int minuteInterval;
7-
final TextStyle textStyle;
7+
final TextStyle? textStyle;
88
final double itemExtent;
99
final Function(Duration) onChange;
1010
final Duration? initialDuration;

0 commit comments

Comments
 (0)