showCustomDatePicker function
Future<Widget?>
showCustomDatePicker(
- {required BuildContext context,
- double adaptWidth = 414.0,
- double adaptHeight = 736.0,
- double textScale = 1.0,
- bool textWeightBold = false,
- Color? cancelColor,
- Color? confirmColor,
- Color? titleBgColor,
- DateTime? initialDate,
- bool restrict = false,
- bool isDarkMode = false,
- required void onConfirm( )}
Implementation
Future<Widget?> showCustomDatePicker(
{required BuildContext context,
double adaptWidth = 414.0,
double adaptHeight = 736.0,
double textScale = 1.0,
bool textWeightBold = false,
Color? cancelColor,
Color? confirmColor,
Color? titleBgColor,
DateTime? initialDate,
bool restrict = false,
bool isDarkMode = false,
required void Function(String, int, int, int) onConfirm}) async {
///restrict is for preventing users from choosing future date, the default is false
int birthYear;
int birthMonth;
int birthDate;
if (initialDate == null) {
birthYear = DateTime.now().year;
birthMonth = DateTime.now().month;
birthDate = DateTime.now().day;
} else {
birthYear = initialDate.year;
birthMonth = initialDate.month;
birthDate = initialDate.day;
}
final mediaQuery = MediaQuery.of(context);
ScreenUtil.init(
BoxConstraints(maxWidth: MediaQuery.of(context).size.width, maxHeight: MediaQuery.of(context).size.height),
designSize: Size(adaptWidth, adaptHeight));
final ScreenUtil screenUtil = ScreenUtil();
final theme = Theme.of(context);
int _birthYear = birthYear;
int _birthMonth = birthMonth;
int _birthDate = birthDate;
int thisYear = DateTime.now().year.toInt();
List<int> yearNum = [];
List<int> leapYear = [];
List<int> monthNum = [];
List<int> lunarMonth = [];
List<int> dateNum = [];
///starts from 1900/01/01
for (var i = 1900; i <= thisYear; i++) {
yearNum.add(i);
}
for (var i = 1900; i <= thisYear; i++) {
if (i % 4 == 0 && i % 100 != 0) {
leapYear.add(i);
} else if (i % 400 == 0) {
leapYear.add(i);
} else {
continue;
}
}
for (var i = 1; i <= 12; i++) {
monthNum.add(i);
}
for (var i = 2; i <= 12; i = i + 2) {
if (i == 8) {
i = i + 1;
lunarMonth.add(i);
continue;
}
lunarMonth.add(i);
}
for (var i = 1; i <= 31; i++) {
dateNum.add(i);
}
List<Center> year = yearNum.map((each) => Center(child: Text("$each年"))).toList();
List<Center> month = monthNum.map((each) {
if (each < 10) {
return Center(child: Text("0$each月"));
}
return Center(child: Text("$each月"));
}).toList();
List<Center> date = dateNum.map((each) {
if (each < 10) {
return Center(child: Text("0$each日"));
}
return Center(child: Text("$each日"));
}).toList();
int indexYear = yearNum.indexOf(birthYear);
int indexMonth = monthNum.indexOf(birthMonth);
int indexDate = dateNum.indexOf(birthDate);
FixedExtentScrollController scrollControllerYear = FixedExtentScrollController(initialItem: indexYear);
FixedExtentScrollController scrollControllerMonth = FixedExtentScrollController(initialItem: indexMonth);
FixedExtentScrollController scrollControllerDate = FixedExtentScrollController(initialItem: indexDate);
Color _shield = isDarkMode ? Colors.black : Color.fromRGBO(245, 245, 245, 1);
return showModalBottomSheet(
enableDrag: false,
context: context,
builder: (context) {
Widget child = Container(
color: isDarkMode ? _shield : Colors.white,
child: Row(children: [
SizedBox(
width: screenUtil.setHeight(16.0),
),
PickerDetail(
screenUtil: screenUtil,
textColor: isDarkMode ? Colors.white.withOpacity(0.8) : Color.fromRGBO(101, 101, 101, 1),
controller: scrollControllerYear,
expand: 2,
curveAmount: -0.3,
leftRadius: screenUtil.setWidth(10.0),
display: year,
method: (index) {
_birthYear = yearNum[index];
_checkLeap(screenUtil, leapYear, _birthDate, scrollControllerDate, yearNum[index], _birthMonth);
if (restrict) {
_checkExceed(screenUtil, yearNum[index], _birthMonth, _birthDate, scrollControllerYear,
scrollControllerMonth, scrollControllerDate, yearNum, monthNum, dateNum);
}
}),
PickerDetail(
screenUtil: screenUtil,
textColor: isDarkMode ? Colors.white.withOpacity(0.8) : Color.fromRGBO(101, 101, 101, 1),
controller: scrollControllerMonth,
expand: 1,
curveAmount: 0.0,
display: month,
method: (index) {
_birthMonth = monthNum[index];
_checkLeap(screenUtil, leapYear, _birthDate, scrollControllerDate, _birthYear, _birthMonth);
_checkLunar(screenUtil, lunarMonth, _birthDate, scrollControllerDate, _birthMonth);
if (restrict) {
_checkExceed(screenUtil, _birthYear, monthNum[index], _birthDate, scrollControllerYear,
scrollControllerMonth, scrollControllerDate, yearNum, monthNum, dateNum);
}
}),
PickerDetail(
screenUtil: screenUtil,
textColor: isDarkMode ? Colors.white.withOpacity(0.8) : Color.fromRGBO(101, 101, 101, 1),
controller: scrollControllerDate,
expand: 2,
curveAmount: 0.3,
rightRadius: screenUtil.setWidth(10.0),
display: date,
method: (index) {
_checkLeap(screenUtil, leapYear, dateNum[index], scrollControllerDate, _birthYear, _birthMonth);
_checkLunar(screenUtil, lunarMonth, dateNum[index], scrollControllerDate, _birthMonth);
if (restrict) {
_checkExceed(screenUtil, _birthYear, _birthMonth, dateNum[index], scrollControllerYear,
scrollControllerMonth, scrollControllerDate, yearNum, monthNum, dateNum);
}
_birthDate = dateNum[index];
}),
SizedBox(width: screenUtil.setHeight(16.0)),
]),
);
return MediaQuery(
data: mediaQuery.copyWith(textScaleFactor: textScale, boldText: textWeightBold),
child: SizedBox(
height: screenUtil.setHeight(300.0),
child: Column(children: [
Container(
color: titleBgColor ?? (isDarkMode ? Color.fromRGBO(10, 10, 10, 1) : Colors.white),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Padding(
padding: EdgeInsets.all(
screenUtil.setHeight(12.0),
),
child: Text(
"取消",
style: TextStyle(
color: cancelColor ??
(isDarkMode ? Colors.white.withOpacity(0.4) : Color.fromRGBO(204, 204, 204, 1)),
fontSize: screenUtil.setHeight(15.5)),
))),
GestureDetector(
onTap: () {
String monthString;
String dateString;
if (_birthMonth < 10) {
monthString = "0${_birthMonth.toString()}";
} else {
monthString = _birthMonth.toString();
}
if (_birthDate < 10) {
dateString = "0${_birthDate.toString()}";
} else {
dateString = _birthDate.toString();
}
onConfirm("${_birthYear.toString()}年$monthString月$dateString日", _birthYear, _birthMonth,
_birthDate);
Navigator.of(context).pop();
},
child: Padding(
padding: EdgeInsets.all(
screenUtil.setHeight(12.0),
),
child: Text(
"確定",
style: TextStyle(
color: confirmColor ?? (isDarkMode ? Colors.white : theme.primaryColor),
fontSize: screenUtil.setHeight(15.5)),
))),
SizedBox(
width: screenUtil.setHeight(5.0),
)
],
),
),
Expanded(
child: isDarkMode
? child
: ShaderMask(
shaderCallback: (rect) => LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
tileMode: TileMode.clamp,
colors: [
_shield.withOpacity(0.0),
_shield.withOpacity(0.2),
_shield.withOpacity(0.8),
_shield.withOpacity(1.0),
_shield.withOpacity(0.8),
_shield.withOpacity(0.2),
_shield.withOpacity(0.0),
]).createShader(rect),
child: child,
),
),
]),
),
);
});
}