diff --git a/analysis_options.yaml b/analysis_options.yaml index 3a7e8a1..b105aa0 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -2,8 +2,7 @@ include: package:lints/recommended.yaml analyzer: exclude: [ "**/*.g.dart", - "**/*.freezed.dart", - "example/**", + "**/*.freezed.dart" ] linter: rules: diff --git a/example/lib/example_widget.dart b/example/lib/example_widget.dart new file mode 100644 index 0000000..c922281 --- /dev/null +++ b/example/lib/example_widget.dart @@ -0,0 +1,692 @@ +import 'dart:developer'; +import 'package:bottom_picker/bottom_picker.dart'; +import 'package:bottom_picker/cupertino/cupertino_date_picker.dart'; +import 'package:bottom_picker/resources/arrays.dart'; +import 'package:example/country_data.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class ExampleApp extends StatelessWidget { + final buttonWidth = 300.0; + + final hugeList = List.generate(10000, (index) => index); + + @override + Widget build(BuildContext context) { + return Container( + color: Color(0xffF6F2F2), + width: double.infinity, + child: Column( + spacing: 10, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openSimpleItemPicker(context); + }, + child: Text('Simple Item picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _displayLongListPicker(context); + }, + child: Text('Long list item picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openDateTimePicker(context); + }, + child: Text('Date time Picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openYearDatePicker(context); + }, + child: Text('Year Picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openDatePicker(context); + }, + child: Text('Date Picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openDatePickerWithButtonStyle(context); + }, + child: Text( + 'Date Picker with button style', + textAlign: TextAlign.center, + ), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openMonthYearPicker(context); + }, + child: Text('Month Year Picker'), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openRangeDatePicker(context); + }, + child: Text('Range Date Picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openRangeTimePicker(context); + }, + child: Text('Range Time Picker'), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openTimePicker(context); + }, + child: Text('Time Picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openTimerPicker(context); + }, + child: Text('Countdown picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openDateTimePicker(context); + }, + child: Text('Workday Picker', textAlign: TextAlign.center), + ), + ), + SizedBox( + width: buttonWidth, + child: ElevatedButton( + onPressed: () { + _openDateTimePickerWeekend(context); + }, + child: Text('Weekend Day Picker', textAlign: TextAlign.center), + ), + ), + ], + ), + ); + } + + void _openSimpleItemPicker(BuildContext context) { + BottomPicker( + items: countryList, + selectedItemIndex: 5, + itemBuilder: (item, index) { + return ListTile( + leading: CircleAvatar( + child: Text(item.name.substring(item.name.length - 2)), + ), + title: Text(item.name), + subtitle: Text('Country ID: ${item.id}'), + ); + }, + itemExtent: 70, + headerBuilder: (context) { + return Row( + children: [ + Expanded( + child: Text( + 'Choose your country', + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15), + ), + ), + InkWell( + onTap: () { + Navigator.pop(context); + }, + child: Icon(Icons.close), + ), + ], + ); + }, + backgroundColor: Colors.yellow.withValues(alpha: 0.6), + bottomPickerTheme: BottomPickerTheme.morningSalad, + onChange: (item) { + log('== Selected Country: ${item.name}, ID: ${item.id}'); + }, + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + instance.dismiss(); + log('Submit button pressed'); + }, + child: Text('Submit'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, + dismissable: true, + filterPredicate: (item, value) { + if (int.tryParse(value) != null) { + return item.id.toString().contains(value); + } + return item.name.toLowerCase().contains(value.toLowerCase()); + }, + searchFieldDecoration: InputDecoration( + hintText: 'Search country', + prefixIcon: Icon(Icons.search), + border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)), + ), + onDismiss: (p0) { + log('Picker dismissed'); + log('== Selected Country: ${p0?.name}, ID: ${p0?.id}'); + }, + ).show(context); + } + + void _displayLongListPicker(BuildContext context) { + BottomPicker( + height: MediaQuery.of(context).size.height * 0.5, + items: hugeList, + itemExtent: 80, + diameterRatio: 50, + searchFieldDecoration: InputDecoration( + hintText: 'Number', + prefixIcon: Icon(Icons.search), + border: OutlineInputBorder( + borderSide: BorderSide(color: Colors.blue), + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + ), + headerBuilder: (context) { + return Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Super long list picker', + style: TextStyle(fontWeight: FontWeight.bold), + ), + Text('Testing a long list of items'), + ], + ), + InkWell( + onTap: () { + Navigator.pop(context); + }, + child: Icon(Icons.close), + ), + ], + ), + ); + }, + onChange: (int index) { + log(index.toString()); + }, + filterPredicate: (item, value) { + return item.toString().contains(value); + }, + buttonBuilder: (instance, context) => ElevatedButton( + onPressed: () { + log('== buttonBuilder Selected Item: ${instance.currentValue}'); + log('Submit button pressed'); + instance.dismiss(); + }, + child: Text('Submit'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ), + onDismiss: (p0) { + log('Picker dismissed'); + log('== onDismiss Selected Item: $p0'); + }, + bottomPickerTheme: BottomPickerTheme.morningSalad, + ).show(context); + } + + void _openDatePicker(BuildContext context) { + BottomPicker.date( + headerBuilder: (context) { + return Row( + children: [ + Text( + 'Set your Birthday', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.blue, + ), + ), + ], + ); + }, + dateOrder: DatePickerDateOrder.dmy, + initialDateTime: DateTime(1996, 10, 22), + maxDateTime: DateTime(1998), + minDateTime: DateTime(1980), + onChange: (index) { + log(index.toString()); + }, + onDismiss: (p0) { + log(p0.toString()); + }, + bottomPickerTheme: BottomPickerTheme.plumPlate, + ).show(context); + } + + void _openYearDatePicker(BuildContext context) { + BottomPicker.year( + headerBuilder: (context) { + return Row( + children: [ + Text( + 'Set your Birthday Year', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.blue, + ), + ), + ], + ); + }, + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + log('== buttonBuilder Selected Year: ${instance.currentValue}'); + log('Submit button pressed'); + instance.dismiss(); + }, + child: Text('Save'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, + initialDateTime: DateTime(1996), + maxDateTime: DateTime(1998), + minDateTime: DateTime(1980), + onChange: (index) { + log(index.toString()); + }, + onDismiss: (p0) { + log(p0.toString()); + }, + bottomPickerTheme: BottomPickerTheme.plumPlate, + ).show(context); + } + + void _openMonthYearPicker(BuildContext context) { + BottomPicker.monthYear( + headerBuilder: (context) { + return Row( + children: [ + Text( + 'Set your Birth Month', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.blue, + ), + ), + ], + ); + }, + initialDateTime: DateTime(1996, 10, 22), + onChange: (index) { + log(index.toString()); + }, + onDismiss: (p0) { + log(p0.toString()); + }, + ).show(context); + } + + void _openDatePickerWithButtonStyle(BuildContext context) { + BottomPicker.date( + headerBuilder: (context) { + return Row( + children: [ + Text( + 'Set your Birthday', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.blue, + ), + ), + ], + ); + }, + dateOrder: DatePickerDateOrder.dmy, + initialDateTime: DateTime(1996, 10, 22), + maxDateTime: DateTime(1998), + minDateTime: DateTime(1980), + onChange: (index) { + log(index.toString()); + }, + bottomPickerTheme: BottomPickerTheme.plumPlate, + buttonBuilder: (instance, context) { + return SizedBox( + width: 200, + child: ElevatedButton( + onPressed: () { + log('== buttonBuilder Selected Item: ${instance.currentValue}'); + log('Submit button pressed'); + instance.dismiss(); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Select date', style: TextStyle(color: Colors.white)), + Icon(Icons.arrow_forward_ios, color: Colors.white, size: 15), + ], + ), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ), + ); + }, + ).show(context); + } + + void _openRangeDatePicker(BuildContext context) { + BottomPicker.range( + headerBuilder: (context) { + return Column( + children: [ + Text( + 'Set date range', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.black, + ), + ), + Text( + 'Please select a first date and an end date', + style: TextStyle(color: Colors.black), + ), + ], + ); + }, + dateOrder: DatePickerDateOrder.mdy, + itemExtent: 50, + pickerTextStyle: TextStyle(fontSize: 15, color: Colors.black), + initialSecondDate: DateTime.now().add(Duration(days: 230)), + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + log( + '== buttonBuilder Selected First Date: ${instance.currentFirstDateTime}', + ); + log( + '== buttonBuilder Selected Second Date: ${instance.currentSecondDateTime}', + ); + log('Confirm button pressed'); + instance.dismiss(); + }, + child: Text('Confirm'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, + onRangePickerDismissed: (p0, p1) { + log(p0.toString()); + log(p1.toString()); + }, + bottomPickerTheme: BottomPickerTheme.plumPlate, + ).show(context); + } + + void _openRangeTimePicker(BuildContext context) { + BottomPicker.rangeTime( + headerBuilder: (context) { + return Column( + children: [ + Text( + 'Set Time range', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.black, + ), + ), + Text( + 'Please select a first time and an end time', + style: TextStyle(color: Colors.black), + ), + ], + ); + }, + showTimeSeparator: true, + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + log( + '== buttonBuilder Selected First Time: ${instance.currentFirstDateTime}', + ); + log( + '== buttonBuilder Selected Second Time: ${instance.currentSecondDateTime}', + ); + log('Submit button pressed'); + instance.dismiss(); + }, + child: Text('Submit'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, + onRangePickerDismissed: (p0, p1) { + log(p0.toString()); + log(p1.toString()); + }, + ).show(context); + } + + void _openTimePicker(BuildContext context) { + BottomPicker.time( + headerBuilder: (context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Set your next meeting time', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.black, + ), + ), + InkWell( + onTap: () { + log('Picker closed'); + Navigator.pop(context); + }, + child: Text( + 'close', + style: TextStyle(decoration: TextDecoration.underline), + ), + ), + ], + ); + }, + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + log('== buttonBuilder Selected Time: ${instance.currentValue}'); + log('Submit button pressed'); + instance.dismiss(); + }, + child: Text('Submit'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, + use24hFormat: false, + bottomPickerTheme: BottomPickerTheme.orange, + initialTime: Time(minutes: 23), + maxTime: Time(hours: 17), + ).show(context); + } + + void _openTimerPicker(BuildContext context) { + BottomPicker.timer( + headerBuilder: (context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Set your next meeting time', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.black, + ), + ), + InkWell( + onTap: () { + log('Picker closed'); + Navigator.pop(context); + }, + child: Text( + 'close', + style: TextStyle(decoration: TextDecoration.underline), + ), + ), + ], + ); + }, + onChange: (p0) => log(p0.toString()), + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + log('== buttonBuilder Selected Time: ${instance.currentValue}'); + log('Submit button pressed'); + instance.dismiss(); + }, + child: Text('Submit'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, + initialTimerDuration: Duration(hours: 6, minutes: 30), + timerPickerMode: CupertinoTimerPickerMode.hms, + ).show(context); + } + + void _openDateTimePicker(BuildContext context) { + BottomPicker.dateTime( + hourPredicate: (hour) { + return hour > 6; + }, + headerBuilder: (context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Set the event exact time and date', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.black, + ), + ), + InkWell( + onTap: () { + log('Picker closed'); + Navigator.pop(context); + }, + child: Text( + 'close', + style: TextStyle(decoration: TextDecoration.underline), + ), + ), + ], + ); + }, + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + log('== buttonBuilder Selected DateTime: ${instance.currentValue}'); + log('Submit button pressed'); + instance.dismiss(); + }, + child: Text('Submit'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, + calendarDays: CupertinoDatePickerWidget.workDays, + ).show(context); + } + + void _openDateTimePickerWeekend(BuildContext context) { + BottomPicker.dateTime( + minuteInterval: 2, + headerBuilder: (context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Set the event exact time and date', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15, + color: Colors.black, + ), + ), + InkWell( + onTap: () { + log('Picker closed'); + Navigator.pop(context); + }, + child: Text( + 'close', + style: TextStyle(decoration: TextDecoration.underline), + ), + ), + ], + ); + }, + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + log('== buttonBuilder Selected DateTime: ${instance.currentValue}'); + log('Submit button pressed'); + instance.dismiss(); + }, + child: Text('Confirm'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, + minDateTime: DateTime(2021, 5, 1), + maxDateTime: DateTime(2021, 8, 2), + initialDateTime: DateTime(2021, 5, 1), + gradientColors: [Color(0xfffdcbf1), Color(0xffe6dee9)], + calendarDays: CupertinoDatePickerWidget.weekend, + ).show(context); + } +} diff --git a/example/lib/main.dart b/example/lib/main.dart index 3fcc858..c432108 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,10 +1,4 @@ -// ignore_for_file: avoid_print - -import 'package:bottom_picker/bottom_picker.dart'; -import 'package:bottom_picker/cupertino/cupertino_date_picker.dart'; -import 'package:bottom_picker/resources/arrays.dart'; -import 'package:example/country_data.dart'; -import 'package:flutter/cupertino.dart'; +import 'package:example/example_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; @@ -29,622 +23,3 @@ class MyApp extends StatelessWidget { ); } } - -class ExampleApp extends StatelessWidget { - final buttonWidth = 300.0; - - final hugeList = List.generate(10000, (index) => index); - - @override - Widget build(BuildContext context) { - return Container( - color: Color(0xffF6F2F2), - width: double.infinity, - child: Column( - spacing: 10, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openSimpleItemPicker(context); - }, - child: Text('Simple Item picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _displayLongListPicker(context); - }, - child: Text('Long list item picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openDateTimePicker(context); - }, - child: Text('Date time Picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openYearDatePicker(context); - }, - child: Text('Year Picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openDatePicker(context); - }, - child: Text('Date Picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openDatePickerWithButtonStyle(context); - }, - child: Text( - 'Date Picker with button style', - textAlign: TextAlign.center, - ), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openMonthYearPicker(context); - }, - child: Text('Month Year Picker'), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openRangeDatePicker(context); - }, - child: Text('Range Date Picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openRangeTimePicker(context); - }, - child: Text('Range Time Picker'), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openTimePicker(context); - }, - child: Text('Time Picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openTimerPicker(context); - }, - child: Text('Countdown picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openDateTimePicker(context); - }, - child: Text('Workday Picker', textAlign: TextAlign.center), - ), - ), - SizedBox( - width: buttonWidth, - child: ElevatedButton( - onPressed: () { - _openDateTimePickerWeekend(context); - }, - child: Text('Weekend Day Picker', textAlign: TextAlign.center), - ), - ), - ], - ), - ); - } - - void _openSimpleItemPicker(BuildContext context) { - BottomPicker( - items: countryList, - selectedItemIndex: 5, - itemBuilder: (item, index) { - return ListTile( - leading: CircleAvatar( - child: Text(item.name.substring(item.name.length - 2)), - ), - title: Text(item.name), - subtitle: Text('Country ID: ${item.id}'), - ); - }, - itemExtent: 70, - headerBuilder: (context) { - return Row( - children: [ - Expanded( - child: Text( - 'Choose your country', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15), - ), - ), - InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Icon(Icons.close), - ), - ], - ); - }, - backgroundColor: Colors.yellow.withValues(alpha: 0.6), - bottomPickerTheme: BottomPickerTheme.morningSalad, - onChange: (item) { - print('== Selected Country: ${item.name}, ID: ${item.id}'); - }, - buttonBuilder: (instance, context) { - return ElevatedButton( - onPressed: () { - instance.dismiss(); - print('Submit button pressed'); - }, - child: Text('Submit'), - style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), - ); - }, - dismissable: true, - filterPredicate: (item, value) { - if (int.tryParse(value) != null) { - return item.id.toString().contains(value); - } - return item.name.toLowerCase().contains(value.toLowerCase()); - }, - searchFieldDecoration: InputDecoration( - hintText: 'Search country', - prefixIcon: Icon(Icons.search), - border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)), - ), - onDismiss: (p0) { - print('Picker dismissed'); - print('== Selected Country: ${p0.name}, ID: ${p0.id}'); - }, - ).show(context); - } - - void _displayLongListPicker(BuildContext context) { - BottomPicker( - height: MediaQuery.of(context).size.height * 0.5, - items: hugeList, - itemExtent: 80, - diameterRatio: 50, - searchFieldDecoration: InputDecoration( - hintText: 'Number', - prefixIcon: Icon(Icons.search), - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.blue), - borderRadius: BorderRadius.all(Radius.circular(10)), - ), - ), - headerBuilder: (context) { - return Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Super long list picker', - style: TextStyle(fontWeight: FontWeight.bold), - ), - Text('Testing a long list of items'), - ], - ), - InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Icon(Icons.close), - ), - ], - ), - ); - }, - onChange: (int index) { - print(index); - }, - filterPredicate: (item, value) { - return item.toString().contains(value); - }, - onSubmit: (int index) { - print(index); - Navigator.pop(context); - }, - onDismiss: (p0) { - print(p0); - }, - bottomPickerTheme: BottomPickerTheme.morningSalad, - ).show(context); - } - - void _openDatePicker(BuildContext context) { - BottomPicker.date( - headerBuilder: (context) { - return Row( - children: [ - Text( - 'Set your Birthday', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.blue, - ), - ), - ], - ); - }, - dateOrder: DatePickerDateOrder.dmy, - initialDateTime: DateTime(1996, 10, 22), - maxDateTime: DateTime(1998), - minDateTime: DateTime(1980), - onChange: (index) { - print(index); - }, - onSubmit: (index) { - print(index); - }, - onDismiss: (p0) { - print(p0); - }, - bottomPickerTheme: BottomPickerTheme.plumPlate, - ).show(context); - } - - void _openYearDatePicker(BuildContext context) { - BottomPicker.year( - headerBuilder: (context) { - return Row( - children: [ - Text( - 'Set your Birthday Year', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.blue, - ), - ), - ], - ); - }, - initialDateTime: DateTime(1996), - maxDateTime: DateTime(1998), - minDateTime: DateTime(1980), - onChange: (index) { - print(index); - }, - onSubmit: (index) { - print(index); - Navigator.pop(context); - }, - onDismiss: (p0) { - print(p0); - }, - bottomPickerTheme: BottomPickerTheme.plumPlate, - ).show(context); - } - - void _openMonthYearPicker(BuildContext context) { - BottomPicker.monthYear( - headerBuilder: (context) { - return Row( - children: [ - Text( - 'Set your Birth Month', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.blue, - ), - ), - ], - ); - }, - initialDateTime: DateTime(1996, 10, 22), - onChange: (index) { - print(index); - }, - onDismiss: (p0) { - print(p0); - }, - ).show(context); - } - - void _openDatePickerWithButtonStyle(BuildContext context) { - BottomPicker.date( - headerBuilder: (context) { - return Row( - children: [ - Text( - 'Set your Birthday', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.blue, - ), - ), - ], - ); - }, - dateOrder: DatePickerDateOrder.dmy, - initialDateTime: DateTime(1996, 10, 22), - maxDateTime: DateTime(1998), - minDateTime: DateTime(1980), - onChange: (index) { - print(index); - }, - onSubmit: (index) { - print(index); - }, - bottomPickerTheme: BottomPickerTheme.plumPlate, - buttonStyle: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(20), - border: Border.all(color: Colors.blue[200]!), - ), - buttonWidth: 200, - buttonContent: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('Select date', style: TextStyle(color: Colors.white)), - Icon(Icons.arrow_forward_ios, color: Colors.white, size: 15), - ], - ), - ), - ).show(context); - } - - void _openRangeDatePicker(BuildContext context) { - BottomPicker.range( - headerBuilder: (context) { - return Column( - children: [ - Text( - 'Set date range', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.black, - ), - ), - Text( - 'Please select a first date and an end date', - style: TextStyle(color: Colors.black), - ), - ], - ); - }, - dateOrder: DatePickerDateOrder.dmy, - initialSecondDate: DateTime.now().add(Duration(days: 230)), - itemExtent: 20, - onRangeDateSubmitPressed: (firstDate, secondDate) { - print(firstDate); - print(secondDate); - }, - onRangePickerDismissed: (p0, p1) { - print(p0); - print(p1); - }, - bottomPickerTheme: BottomPickerTheme.plumPlate, - ).show(context); - } - - void _openRangeTimePicker(BuildContext context) { - BottomPicker.rangeTime( - headerBuilder: (context) { - return Column( - children: [ - Text( - 'Set Time range', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.black, - ), - ), - Text( - 'Please select a first time and an end time', - style: TextStyle(color: Colors.black), - ), - ], - ); - }, - showTimeSeparator: true, - bottomPickerTheme: BottomPickerTheme.plumPlate, - onRangeTimeSubmitPressed: (firstDate, secondDate) { - print(firstDate); - print(secondDate); - }, - closeOnSubmit: true, - onRangePickerDismissed: (p0, p1) { - print(p0); - print(p1); - }, - ).show(context); - } - - void _openTimePicker(BuildContext context) { - BottomPicker.time( - headerBuilder: (context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Set your next meeting time', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.black, - ), - ), - InkWell( - onTap: () { - print('Picker closed'); - Navigator.pop(context); - }, - child: Text( - 'close', - style: TextStyle(decoration: TextDecoration.underline), - ), - ), - ], - ); - }, - use24hFormat: false, - onSubmit: (index) { - print(index); - }, - bottomPickerTheme: BottomPickerTheme.orange, - initialTime: Time(minutes: 23), - maxTime: Time(hours: 17), - ).show(context); - } - - void _openTimerPicker(BuildContext context) { - BottomPicker.timer( - headerBuilder: (context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Set your next meeting time', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.black, - ), - ), - InkWell( - onTap: () { - print('Picker closed'); - Navigator.pop(context); - }, - child: Text( - 'close', - style: TextStyle(decoration: TextDecoration.underline), - ), - ), - ], - ); - }, - onChange: (p0) => print(p0), - onSubmit: (index) { - print(index); - }, - initialTimerDuration: Duration(hours: 6, minutes: 30), - timerPickerMode: CupertinoTimerPickerMode.hms, - ).show(context); - } - - void _openDateTimePicker(BuildContext context) { - BottomPicker.dateTime( - hourPredicate: (hour) { - return hour > 6; - }, - headerBuilder: (context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Set the event exact time and date', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.black, - ), - ), - InkWell( - onTap: () { - print('Picker closed'); - Navigator.pop(context); - }, - child: Text( - 'close', - style: TextStyle(decoration: TextDecoration.underline), - ), - ), - ], - ); - }, - onSubmit: (date) { - print(date); - }, - calendarDays: CupertinoDatePickerWidget.workDays, - ).show(context); - } - - void _openDateTimePickerWeekend(BuildContext context) { - BottomPicker.dateTime( - minuteInterval: 2, - headerBuilder: (context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Set the event exact time and date', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 15, - color: Colors.black, - ), - ), - InkWell( - onTap: () { - print('Picker closed'); - Navigator.pop(context); - }, - child: Text( - 'close', - style: TextStyle(decoration: TextDecoration.underline), - ), - ), - ], - ); - }, - onSubmit: (date) { - print(date); - }, - minDateTime: DateTime(2021, 5, 1), - maxDateTime: DateTime(2021, 8, 2), - initialDateTime: DateTime(2021, 5, 1), - gradientColors: [Color(0xfffdcbf1), Color(0xffe6dee9)], - calendarDays: CupertinoDatePickerWidget.weekend, - ).show(context); - } -} diff --git a/lib/bottom_picker.dart b/lib/bottom_picker.dart index 4669839..2f3c3d8 100644 --- a/lib/bottom_picker.dart +++ b/lib/bottom_picker.dart @@ -6,7 +6,6 @@ import 'package:bottom_picker/resources/context_extension.dart'; import 'package:bottom_picker/resources/extensions.dart'; import 'package:bottom_picker/resources/time.dart'; import 'package:bottom_picker/widgets/bottom_picker_button.dart'; -import 'package:bottom_picker/widgets/close_icon.dart'; import 'package:bottom_picker/widgets/date_picker.dart'; import 'package:bottom_picker/widgets/range_picker.dart'; import 'package:bottom_picker/widgets/simple_picker.dart'; @@ -19,6 +18,8 @@ import 'package:flutter/services.dart'; export 'package:bottom_picker/resources/time.dart'; +typedef SearchItemPredicate = bool Function(T, String); + // ignore: must_be_immutable class BottomPicker extends StatefulWidget { ///The dateTime picker mode @@ -74,6 +75,7 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { dateOrder = null; onRangeDateSubmitPressed = null; @@ -122,6 +124,7 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { datePickerMode = CupertinoDatePickerMode.date; bottomPickerType = BottomPickerType.dateTime; @@ -165,12 +168,12 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { datePickerMode = CupertinoDatePickerMode.date; bottomPickerType = BottomPickerType.year; use24hFormat = false; onRangeDateSubmitPressed = null; - displayCloseIcon = false; assertInitialValues(); } @@ -210,6 +213,7 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { datePickerMode = CupertinoDatePickerMode.monthYear; bottomPickerType = BottomPickerType.dateTime; @@ -260,6 +264,7 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { datePickerMode = CupertinoDatePickerMode.dateAndTime; bottomPickerType = BottomPickerType.dateTime; @@ -306,6 +311,7 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { datePickerMode = CupertinoDatePickerMode.time; bottomPickerType = BottomPickerType.time; @@ -352,6 +358,7 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { dateOrder = null; onRangeDateSubmitPressed = null; @@ -400,6 +407,7 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { datePickerMode = CupertinoDatePickerMode.date; bottomPickerType = BottomPickerType.rangeDate; @@ -409,7 +417,6 @@ class BottomPicker extends StatefulWidget { onDismiss = null; displaySubmitButton = true; use24hFormat = true; - assert(onRangeDateSubmitPressed != null); assertInitialValues(); if (minSecondDate != null && initialSecondDate != null) { assert( @@ -464,6 +471,7 @@ class BottomPicker extends StatefulWidget { @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, @Deprecated('Use buttonBuilder instead') this.buttonPadding, @Deprecated('Use buttonBuilder instead') this.buttonWidth, + this.pickerTextStyle, }) { datePickerMode = CupertinoDatePickerMode.time; bottomPickerType = BottomPickerType.rangeTime; @@ -472,7 +480,6 @@ class BottomPicker extends StatefulWidget { onSubmit = null; onDismiss = null; displaySubmitButton = true; - assert(onRangeTimeSubmitPressed != null); assertInitialValues(); if (minSecondTime != null && initialSecondTime != null) { assert(initialSecondTime!.isAfter(minSecondTime!)); @@ -482,23 +489,9 @@ class BottomPicker extends StatefulWidget { } } - /// Bottom picker title widget - Widget? pickerTitle; - /// Renders the header component of the bottom picker final Widget Function(BuildContext context)? headerBuilder; - ///Bottom picker description widget - Widget? pickerDescription; - - ///The padding applied on the title - ///by default it is set with zero values - EdgeInsetsGeometry? titlePadding; - - ///Title widget alignment inside the stack - ///by default the title will be aligned left/right depends on `layoutOrientation` - Alignment? titleAlignment; - ///defines whether the bottom picker is dismissable or not ///by default it's set to false /// @@ -522,7 +515,7 @@ class BottomPicker extends StatefulWidget { /// Predicate function used to filter items in the search field /// if not null the search field will be displayed and the user can filter the items based on the predicate /// Takes two parameters: the item and the search query, and returns a boolean indicating whether the item should be filtered out or not. - bool Function(T, String)? filterPredicate; + SearchItemPredicate? filterPredicate; /// The search field text input action, which determines the action button on the keyboard. TextInputAction? textInputAction; @@ -533,12 +526,11 @@ class BottomPicker extends StatefulWidget { ///Nullable function invoked when clicking on submit button ///if the picker type is date/time/dateTime it will return DateTime value ///else it will return the index of the selected item - /// - late Function(T)? onSubmit; + late Function(T?)? onSubmit; /// Nullable function invoked when the picker get dismissed /// it will return the selected value - late Function(T)? onDismiss; + late Function(T?)? onDismiss; ///Invoked when clicking on the close button Function? onCloseButtonPressed; @@ -641,24 +633,6 @@ class BottomPicker extends StatefulWidget { ///by default it's 35 late double itemExtent; - ///indicate whether the close icon will be rendred or not - /// by default `displayCloseIcon = true` - bool? displayCloseIcon; - - /// Renders the close widget if it's null and [displayCloseIcon] is true - /// the default close icon is rendered. - /// Note if closeWidget is provided onClosePressed won't be triggered - /// since you need to handle all actions on the provided widget. - Widget? closeWidget; - - ///the close icon color - ///by default `closeIconColor = Colors.black` - Color? closeIconColor; - - ///the close icon size - ///by default `closeIconSize = 20` - double? closeIconSize; - ///the layout orientation of the bottom picker ///by default the orientation is set to LTR ///``` @@ -680,7 +654,7 @@ class BottomPicker extends StatefulWidget { ///invoked when pressing on the submit button when using range picker ///it return two dates (first date, end date) ///required when using [BottomPicker.range] - late Function(DateTime, DateTime)? onRangeDateSubmitPressed; + late Function(DateTime?, DateTime?)? onRangeDateSubmitPressed; ///the minimum first date in the date range picker ///not required if null no minimum will be set in the date picker @@ -745,11 +719,11 @@ class BottomPicker extends StatefulWidget { /// Invoked when pressing on the submit button when using range picker /// it return two dates (first time, end time) /// required when using [BottomPicker.rangeTime] - late Function(DateTime, DateTime)? onRangeTimeSubmitPressed; + late Function(DateTime?, DateTime?)? onRangeTimeSubmitPressed; /// Function invoked when the picker is dismissed used with range picker /// and time range picker. - late Function(DateTime, DateTime)? onRangePickerDismissed; + late Function(DateTime?, DateTime?)? onRangePickerDismissed; ///the minimum first time in the time range picker ///not required if null no minimum will be set in the time picker @@ -797,6 +771,48 @@ class BottomPicker extends StatefulWidget { BuildContext? _context; bool disposed = false; + BottomPickerState? _state; + + T? get currentValue { + if (_state == null) return null; + + if (bottomPickerType == BottomPickerType.simple) { + return _state!._selectedItem as T; + } else if (bottomPickerType == BottomPickerType.dateTime || + bottomPickerType == BottomPickerType.year) { + return _state!._selectedDateTime as T; + } else if (bottomPickerType == BottomPickerType.time) { + return _state!._selectedDateTime as T; + } else if (bottomPickerType == BottomPickerType.timer) { + return _state!._selectedTimerDuration as T; + } else if (bottomPickerType == BottomPickerType.rangeDate || + bottomPickerType == BottomPickerType.rangeTime) { + throw Exception( + 'Use currentFirstDateTime and currentSecondDateTime for range picker', + ); + } + return null; + } + + DateTime? get currentFirstDateTime { + if (_state == null) return null; + + if (bottomPickerType == BottomPickerType.rangeDate || + bottomPickerType == BottomPickerType.rangeTime) { + return _state!._selectedFirstDateTime; + } + return null; + } + + DateTime? get currentSecondDateTime { + if (_state == null) return null; + + if (bottomPickerType == BottomPickerType.rangeDate || + bottomPickerType == BottomPickerType.rangeTime) { + return _state!._selectedSecondDateTime; + } + return null; + } ///display the bottom picker popup ///[context] the app context to display the popup @@ -840,31 +856,37 @@ class BottomPicker extends StatefulWidget { } class BottomPickerState extends State> { - late int selectedItemIndex; - late T selectedItem; - late DateTime selectedDateTime; - Duration? selectedTimerDuration; - - late DateTime selectedFirstDateTime = - widget.initialFirstDate ?? DateTime.now(); - late DateTime selectedSecondDateTime = - widget.initialSecondDate ?? DateTime.now(); - late final List? originalItemList = widget.items; late List? displayedItemList = originalItemList; + int _selectedItemIndex = 0; + T? _selectedItem; + DateTime? _selectedDateTime; + Duration? _selectedTimerDuration; + DateTime? _selectedSecondDateTime; + DateTime? _selectedFirstDateTime; + @override void initState() { super.initState(); + widget._state = this; if (widget.bottomPickerType == BottomPickerType.simple) { - selectedItemIndex = widget.selectedItemIndex; - selectedItem = widget.items![selectedItemIndex]; + _selectedItemIndex = widget.selectedItemIndex; + _selectedItem = widget.items![_selectedItemIndex]; } else if (widget.bottomPickerType == BottomPickerType.time) { - selectedDateTime = (widget.initialTime ?? Time.now()).toDateTime; + _selectedDateTime = (widget.initialTime ?? Time.now()).toDateTime; } else if (widget.bottomPickerType == BottomPickerType.timer) { - selectedTimerDuration = widget.initialTimerDuration ?? Duration.zero; + _selectedTimerDuration = widget.initialTimerDuration ?? Duration.zero; } else { - selectedDateTime = widget.initialDateTime ?? DateTime.now(); + _selectedDateTime = widget.initialDateTime ?? DateTime.now(); + } + + if (widget.bottomPickerType == BottomPickerType.rangeDate) { + _selectedFirstDateTime = widget.initialFirstDate ?? DateTime.now(); + _selectedSecondDateTime = widget.initialSecondDate ?? DateTime.now(); + } else if (widget.bottomPickerType == BottomPickerType.rangeTime) { + _selectedFirstDateTime = widget.initialFirstTime ?? DateTime.now(); + _selectedSecondDateTime = widget.initialSecondTime ?? DateTime.now(); } if (kIsWeb || (!Platform.isIOS && !Platform.isAndroid)) { @@ -890,20 +912,24 @@ class BottomPickerState extends State> { if (widget.bottomPickerType == BottomPickerType.rangeDate || widget.bottomPickerType == BottomPickerType.rangeTime) { widget.onRangePickerDismissed?.call( - selectedFirstDateTime, - selectedSecondDateTime, + _selectedFirstDateTime, + _selectedSecondDateTime, ); } else if (widget.bottomPickerType == BottomPickerType.simple) { - widget.onDismiss?.call(selectedItem); + widget.onDismiss?.call(_selectedItem as T); } else if (widget.bottomPickerType == BottomPickerType.timer) { - widget.onDismiss?.call(selectedTimerDuration as T); + widget.onDismiss?.call(_selectedTimerDuration as T); } else { - widget.onDismiss?.call(selectedDateTime as T); + widget.onDismiss?.call(_selectedDateTime as T); } super.dispose(); } + static BottomPickerState? of(BuildContext context) { + return context.findAncestorStateOfType>(); + } + @override Widget build(BuildContext context) { if (widget.useSafeArea) { @@ -937,35 +963,16 @@ class BottomPickerState extends State> { child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - Padding( - padding: widget.headerBuilder == null - ? widget.titlePadding ?? const EdgeInsets.all(0) - : EdgeInsets.zero, - child: Row( - children: [ - if (widget.headerBuilder != null) - Expanded( - child: widget.headerBuilder!( - context, - ), + Row( + children: [ + if (widget.headerBuilder != null) + Expanded( + child: widget.headerBuilder!( + context, ), - if (widget.headerBuilder == null && - widget.pickerTitle != null) - Expanded(child: widget.pickerTitle!), - if (widget.headerBuilder == null && - (widget.displayCloseIcon ?? true)) - widget.closeWidget ?? - CloseIcon( - onPress: _closeBottomPicker, - iconColor: widget.closeIconColor, - closeIconSize: widget.closeIconSize, - ), - ], - ), + ), + ], ), - if (widget.headerBuilder == null && - widget.pickerDescription != null) - widget.pickerDescription!, ], ), ), @@ -996,11 +1003,11 @@ class BottomPickerState extends State> { return; } final item = displayedItemList![index]; - selectedItem = item; - selectedItemIndex = originalItemList!.indexOf(item); + _selectedItem = item; + _selectedItemIndex = originalItemList!.indexOf(item); widget.onChange?.call(item); }, - selectedItemIndex: widget.selectedItemIndex, + selectedItemIndex: _selectedItemIndex, textStyle: widget.pickerTextStyle, itemExtent: widget.itemExtent, selectionOverlay: widget.selectionOverlay, @@ -1016,7 +1023,7 @@ class BottomPickerState extends State> { initialDuration: widget.initialTimerDuration, onChange: (p0) { widget.onChange?.call(p0 as T); - selectedTimerDuration = p0; + _selectedTimerDuration = p0; }, secondInterval: widget.timerSecondsInterval, pickerThemeData: widget.pickerThemeData, @@ -1029,7 +1036,7 @@ class BottomPickerState extends State> { minDateTime: widget.minTime.toDateTime, mode: widget.datePickerMode, onDateChanged: (DateTime date) { - selectedDateTime = date; + _selectedDateTime = date; widget.onChange?.call(date as T); }, use24hFormat: widget.use24hFormat, @@ -1047,7 +1054,12 @@ class BottomPickerState extends State> { minDateTime: widget.minDateTime, mode: widget.datePickerMode, onDateChanged: (DateTime date) { - selectedDateTime = date; + if (widget.calendarDays.isNotEmpty && + !widget.calendarDays + .contains(date.weekday)) { + return; + } + _selectedDateTime = date; widget.onChange?.call(date as T); }, use24hFormat: widget.use24hFormat, @@ -1056,6 +1068,7 @@ class BottomPickerState extends State> { itemExtent: widget.itemExtent, showTimeSeparator: widget.showTimeSeparator, pickerThemeData: widget.pickerThemeData, + calendarDays: widget.calendarDays, hourPredicate: widget.hourPredicate, ) : widget.bottomPickerType == BottomPickerType.year @@ -1064,7 +1077,7 @@ class BottomPickerState extends State> { maxDateTime: widget.maxDateTime, minDateTime: widget.minDateTime, onDateChanged: (DateTime date) { - selectedDateTime = date; + _selectedDateTime = date; widget.onChange?.call(date as T); }, itemExtent: widget.itemExtent, @@ -1085,10 +1098,10 @@ class BottomPickerState extends State> { minSecondDateTime: widget.minSecondTime, onFirstDateChanged: (DateTime date) { - selectedFirstDateTime = date; + _selectedFirstDateTime = date; }, onSecondDateChanged: (DateTime date) { - selectedSecondDateTime = date; + _selectedSecondDateTime = date; }, dateOrder: widget.dateOrder, textStyle: widget.pickerTextStyle, @@ -1112,10 +1125,10 @@ class BottomPickerState extends State> { minSecondDateTime: widget.minSecondDate, onFirstDateChanged: (DateTime date) { - selectedFirstDateTime = date; + _selectedFirstDateTime = date; }, onSecondDateChanged: (DateTime date) { - selectedSecondDateTime = date; + _selectedSecondDateTime = date; }, dateOrder: widget.dateOrder, textStyle: widget.pickerTextStyle, @@ -1141,25 +1154,25 @@ class BottomPickerState extends State> { if (widget.bottomPickerType == BottomPickerType.rangeDate) { widget.onRangeDateSubmitPressed?.call( - selectedFirstDateTime, - selectedSecondDateTime, + _selectedFirstDateTime, + _selectedSecondDateTime, ); } else if (widget.bottomPickerType == BottomPickerType.rangeTime) { widget.onRangeTimeSubmitPressed?.call( - selectedFirstDateTime, - selectedSecondDateTime, + _selectedFirstDateTime, + _selectedSecondDateTime, ); } else if (widget.bottomPickerType == BottomPickerType.dateTime || widget.bottomPickerType == BottomPickerType.time || widget.bottomPickerType == BottomPickerType.year) { - widget.onSubmit?.call(selectedDateTime as T); + widget.onSubmit?.call(_selectedDateTime as T?); } else if (widget.bottomPickerType == BottomPickerType.timer) { - widget.onSubmit?.call(selectedTimerDuration as T); + widget.onSubmit?.call(_selectedTimerDuration as T?); } else { - widget.onSubmit?.call(selectedItem); + widget.onSubmit?.call(_selectedItem); } if (widget.closeOnSubmit ?? false) { @@ -1194,10 +1207,4 @@ class BottomPickerState extends State> { } return false; } - - /// Close the bottom picker - void _closeBottomPicker() { - widget.onCloseButtonPressed?.call(); - Navigator.pop(context); - } } diff --git a/lib/widgets/close_icon.dart b/lib/widgets/close_icon.dart deleted file mode 100644 index a48f555..0000000 --- a/lib/widgets/close_icon.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A close icon widget that can be used to close the picker. -class CloseIcon extends StatelessWidget { - /// The callback function that is called when the close icon is pressed. - final Function() onPress; - - /// The color of the close icon. - final Color? iconColor; - - /// The size of the close icon. - final double? closeIconSize; - - const CloseIcon({ - super.key, - required this.onPress, - required this.iconColor, - required this.closeIconSize, - }); - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: onPress, - child: Icon( - Icons.close, - color: iconColor, - size: closeIconSize, - ), - ); - } -} diff --git a/lib/widgets/year_picker.dart b/lib/widgets/year_picker.dart index 721cb15..4f213b7 100644 --- a/lib/widgets/year_picker.dart +++ b/lib/widgets/year_picker.dart @@ -66,13 +66,7 @@ class _BottomYearDatePicker extends State { @override Widget build(BuildContext context) { return SimplePicker( - items: years - .map( - (year) => Text( - year.toString(), - ), - ) - .toList(), + items: years, onChange: (index) { widget.onDateChanged( DateTime( diff --git a/test/simple_bottom_picker_test.dart b/test/simple_bottom_picker_test.dart index 45ce8f2..75f8931 100644 --- a/test/simple_bottom_picker_test.dart +++ b/test/simple_bottom_picker_test.dart @@ -107,7 +107,9 @@ void main() { }, items: items, onSubmit: (p0) { - index = p0; + if (p0 != null) { + index = p0; + } }, ), ),