本文最后更新于 532 天前
import 'package:flutter/material.dart';
class CalendarWidget extends StatefulWidget {
// 选择器范围
DateTime startTime;
DateTime endTime;
// 日期文本字体大小
TextStyle? style;
// 头部 周文本样式
TextStyle? headerStyle;
// 日期容器大小
double? size;
// 选择器高度
double? height;
// 选择器padding
EdgeInsets? padding;
// 选中回调
Function(DateTime dateTime)? onTapTime;
CalendarWidget({
Key? key,
required this.startTime,
required this.endTime,
this.style,
this.size,
this.height,
this.padding,
this.onTapTime,
this.headerStyle,
}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
/*
{
end:"2024-12-01", //最后可显示日历的日期
hot:{"2023-07-05":"2023-08-31","2024-07-05":"2024-08-31"}, //所有暑假段
code:{"2023-01-15":"2023-02-06","2024-01-15":"2024-02-06"}, //所有寒假段
extholiday:["2023-05-03","2023-05-04"], //额外假日列表
extworkday:["2023-06-08","2023-06-09"] //额外工作日列表
}
*/
late PageController _pageController;
List<WeekItem> source = [];
late DateTime start;
late DateTime end;
// 记录之前页码 用于清除之前页选中效果
int beforeChoosePageIndex = -1;
@override
void initState() {
DateTime currentDate = DateTime.now();
start = widget.startTime;
end = widget.endTime;
// 初始化构建三页数据
List<ItemConfig> weekDates = getWeekDates(currentDate);
source.add(WeekItem()..week = weekDates);
source.insert(0, WeekItem()..week = getPreviousWeek(weekDates[0].dateTime));
source.add(WeekItem()..week = getNextWeek(weekDates[6].dateTime));
_pageController = PageController(initialPage: 1);
beforeChoosePageIndex = 1;
super.initState();
}
@override
void dispose() {
super.dispose();
_pageController.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 15,vertical: 15),
child: Column(
children: [
Row(
children: List.generate(7, (index) => Expanded(
child: Text(_getDayText(index),textAlign: TextAlign.center,style: widget.headerStyle??const TextStyle(
fontSize: 12,
color: Color(0xFF999999)
),),
)),
),
Padding(
padding: widget.padding??const EdgeInsets.only(top: 12.0),
child: SizedBox(
height: widget.height??36,
child: PageView.builder(
controller: _pageController,
onPageChanged: (page) {
if(page == 0) {
setState(() {
source.insert(0,WeekItem()..week = getPreviousWeek(source[0].week[0].dateTime));
_pageController.jumpTo(_pageController.position.pixels + _pageController.position.viewportDimension);
});
} else if(page == source.length - 1) {
setState(() {
source.add(WeekItem()..week = getNextWeek(source[source.length - 1].week[6].dateTime));
});
}
},
itemBuilder: (BuildContext context, int index) {
WeekItem weekItem = source[index];
return Row(
children: List.generate(7, (index) {
DateTime now = weekItem.week[index].dateTime;
// 是否超出startTime 是否超出endTime
bool isEnable = now.isBefore(start) || end.isBefore(now);
bool isToday = _isSameDate(now,DateTime.now());
bool isChoose = weekItem.chooseIndex == index;
String extraTip = weekItem.week[index].extraTip;
Widget dateTimeWidget = Text("{now.day}",style: widget.style??TextStyle(
fontWeight: FontWeight.w600,
fontSize: 18,
color: isChoose ? Colors.white : const Color(0xFF666666)
));
return Expanded(
child: UnconstrainedBox(
child: GestureDetector(
onTap: () {
// 重置之前选中状态
if(beforeChoosePageIndex != _pageController.page && beforeChoosePageIndex >= 0 && beforeChoosePageIndexdateTime, extraTip: $extraTip}';
}
}