import 'package:calendar_date_picker2/calendar_date_picker2.dart'; import 'package:flutter/material.dart'; dynamic textValue; dynamic constructionDataAll; class CanlenderSelect extends StatefulWidget { final String title; final List constructionData; final double height; final void Function(String?) getSelectedValue; const CanlenderSelect( {super.key, required this.title, required this.constructionData, required this.getSelectedValue, required this.height}); @override State createState() => _CanlenderSelectState(); } class _CanlenderSelectState extends State { //初始选中 List _dialogCalendarPickerValue = [ constructionDataAll == null ? DateTime.now() : constructionDataAll[0] ]; bool _initialized = false; //因为父页面加载的时候会执行tools这时候init就会执行,导致日期不会初始化选中,使用update配合一个flag,让第一次数据加载的时候,初始化选中 @override void didUpdateWidget(CanlenderSelect oldWidget) { super.didUpdateWidget(oldWidget); if (!_initialized && oldWidget.constructionData != widget.constructionData) { setState(() { // print(widget.constructionData?.first); if (widget.constructionData.isNotEmpty) { _dialogCalendarPickerValue = [ DateTime.parse(widget.constructionData.first) ]; } _initialized = true; }); } } @override void initState() { super.initState(); } @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; var dayTextStyle = TextStyle( color: isDarkMode ? Colors.white : Colors.black, fontWeight: FontWeight.w700); final weekendTextStyle = TextStyle(color: Colors.grey[500], fontWeight: FontWeight.w600); final config = CalendarDatePicker2WithActionButtonsConfig( // buttonPadding: EdgeInsets.only(left: 10,right: 10), // cancelButtonTextStyle: TextStyle(fontSize: 8,color: Colors.purple,fontWeight: FontWeight.w700), // okButtonTextStyle: TextStyle(fontSize: 8,color: Colors.purple,fontWeight: FontWeight.w700), // controlsHeight: 16, gapBetweenCalendarAndButtons: 0, dayTextStyle: dayTextStyle, calendarType: CalendarDatePicker2Type.single, lastDate: DateTime.now(), selectedDayHighlightColor: Colors.purple[800], closeDialogOnCancelTapped: true, firstDayOfWeek: 1, weekdayLabelTextStyle: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, fontWeight: FontWeight.bold, ), controlsTextStyle: TextStyle( color: isDarkMode ? Colors.white : Colors.black, fontSize: 15, fontWeight: FontWeight.bold, ), centerAlignModePicker: true, customModePickerIcon: const SizedBox(), selectedDayTextStyle: dayTextStyle.copyWith( color: isDarkMode ? Colors.black : Colors.white), dayTextStylePredicate: ({required date}) { TextStyle? textStyle; if (date.weekday == DateTime.saturday || date.weekday == DateTime.sunday) { textStyle = weekendTextStyle; } // if (DateUtils.isSameDay(date, DateTime(2021, 1, 25))) { // textStyle = anniversaryTextStyle; // } return textStyle; }, dayBuilder: ({ required date, textStyle, decoration, isSelected, isDisabled, isToday, }) { Widget? dayWidget; for (var i = 0; i < widget.constructionData.length; i++) { if (date.year == int.parse( widget.constructionData[i].toString().split("-")[0]) && date.month == int.parse( widget.constructionData[i].toString().split("-")[1]) && date.day == int.parse( widget.constructionData[i].toString().split("-")[2])) { dayWidget = Container( decoration: decoration, child: Center( child: Stack( alignment: AlignmentDirectional.center, children: [ Text( MaterialLocalizations.of(context).formatDecimal(date.day), style: textStyle, ), Padding( padding: const EdgeInsets.only(top: 27.5), child: Container( height: 5, width: 5, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: Colors.green, ), ), ), ], ), ), ); } } return dayWidget; }, yearBuilder: ({ required year, decoration, isCurrentYear, isDisabled, isSelected, textStyle, }) { return Center( child: Container( decoration: decoration, height: 36, width: 72, child: Center( child: Semantics( selected: isSelected, button: true, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( year.toString(), style: textStyle, ), if (isWorkedYear(year)) Container( padding: const EdgeInsets.all(5), margin: const EdgeInsets.only(left: 5), decoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.green, ), ), ], ), ), ), ), ); }, ); return Padding( padding: const EdgeInsets.all(0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () async { if (widget.height > 410) { final values = await showCalendarDatePicker2Dialog( dialogBackgroundColor: isDarkMode ? Colors. black: Colors.white, context: context, config: config, // dialogSize: const Size(300, 321), dialogSize: const Size(300, 410), borderRadius: BorderRadius.circular(15), value: _dialogCalendarPickerValue, ); if (values != null) { // ignore: avoid_print // print(_getValueText( // config.calendarType, // values, // )); setState(() { _dialogCalendarPickerValue = values; textValue = values; }); widget.getSelectedValue(values[0].toString().split(" ")[0]); } } }, child: Text(textValue == null ? (widget.constructionData.isEmpty) ? "" : widget.constructionData[0] : textValue[0].toString().split(" ")[0]), ), ], ), ); } bool isWorkedYear(year) { for (var i = 0; i < widget.constructionData.length; i++) { if (int.parse(widget.constructionData[i].toString().split("-")[0]) == year) { return true; } } return false; } String getValueText( CalendarDatePicker2Type datePickerType, List values, ) { values = values.map((e) => e != null ? DateUtils.dateOnly(e) : null).toList(); var valueText = (values.isNotEmpty ? values[0] : null) .toString() .replaceAll('00:00:00.000', ''); if (datePickerType == CalendarDatePicker2Type.multi) { valueText = values.isNotEmpty ? values .map((v) => v.toString().replaceAll('00:00:00.000', '')) .join(', ') : 'null'; } else if (datePickerType == CalendarDatePicker2Type.range) { if (values.isNotEmpty) { final startDate = values[0].toString().replaceAll('00:00:00.000', ''); final endDate = values.length > 1 ? values[1].toString().replaceAll('00:00:00.000', '') : 'null'; valueText = '$startDate to $endDate'; } else { return 'null'; } } return valueText; } }