import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/material.dart'; import 'package:flutter_custom_calendar/constants/constants.dart'; import 'package:flutter_custom_calendar/utils/LogUtil.dart'; import 'package:flutter_custom_calendar/utils/date_util.dart'; import 'package:flutter_custom_calendar/widget/week_view_pager.dart'; import 'package:provider/provider.dart'; import '../calendar_provider.dart'; import '../controller.dart'; import 'month_view_pager.dart'; /** * 暂时默认是周一开始的 */ //由于旧的代码关系。。所以现在需要抽出一个StatefulWidget放在StatelessWidget里面 class CalendarViewWidget extends StatefulWidget { //整体的背景设置 final BoxDecoration? boxDecoration; //日历的padding和margin final EdgeInsetsGeometry padding; final EdgeInsetsGeometry margin; //默认是屏幕宽度/7 final double? itemSize; //日历item之间的竖直方向间距,默认10 final double verticalSpacing; //自定义日历item final DayWidgetBuilder dayWidgetBuilder; final WeekBarItemWidgetBuilder weekBarItemWidgetBuilder; //控制器 final CalendarController calendarController; CalendarViewWidget( {Key? key, this.dayWidgetBuilder = defaultCustomDayWidget, this.weekBarItemWidgetBuilder = defaultWeekBarWidget, required this.calendarController, this.boxDecoration, this.padding = EdgeInsets.zero, this.margin = EdgeInsets.zero, this.verticalSpacing = 10, this.itemSize}) : super(key: key); @override _CalendarViewWidgetState createState() => _CalendarViewWidgetState(); } class _CalendarViewWidgetState extends State { @override void initState() { //初始化一些数据,一些跟状态有关的要放到provider中 widget.calendarController.calendarProvider.initData( calendarConfiguration: widget.calendarController.calendarConfiguration, padding: widget.padding, margin: widget.margin, itemSize: widget.itemSize, verticalSpacing: widget.verticalSpacing, dayWidgetBuilder: widget.dayWidgetBuilder, weekBarItemWidgetBuilder: widget.weekBarItemWidgetBuilder); super.initState(); } @override void dispose() { // widget.calendarController.clearData(); super.dispose(); } @override Widget build(BuildContext context) { return ChangeNotifierProvider.value( value: widget.calendarController.calendarProvider, child: Container( //外部可以自定义背景设置 decoration: widget.boxDecoration, padding: widget.padding, margin: widget.margin, //使用const,保证外界的setState不会刷新日历这个widget child: CalendarContainer(widget.calendarController)), ); } } class CalendarContainer extends StatefulWidget { final CalendarController calendarController; const CalendarContainer(this.calendarController); @override CalendarContainerState createState() => CalendarContainerState(); } class CalendarContainerState extends State with SingleTickerProviderStateMixin { double? itemHeight; double? totalHeight; late bool expand; late CalendarProvider calendarProvider; List widgets = []; int index = 0; @override void initState() { super.initState(); calendarProvider = Provider.of(context, listen: false); expand = calendarProvider.expandStatus.value; if (calendarProvider.calendarConfiguration!.showMode == CalendarConstants.MODE_SHOW_ONLY_WEEK) { widgets.add(const WeekViewPager()); } else if (calendarProvider.calendarConfiguration!.showMode == CalendarConstants.MODE_SHOW_WEEK_AND_MONTH) { widgets.add(const MonthViewPager()); widgets.add(const WeekViewPager()); index = 1; } else if (calendarProvider.calendarConfiguration!.showMode == CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) { widgets.add(const MonthViewPager()); widgets.add(const WeekViewPager()); index = 0; } else { //默认是只显示月视图 widgets.add(const MonthViewPager()); } expand = calendarProvider.expandStatus.value; //如果需要视图切换的话,才需要添加监听,不然不需要监听变化 if (calendarProvider.calendarConfiguration!.showMode == CalendarConstants.MODE_SHOW_WEEK_AND_MONTH || calendarProvider.calendarConfiguration!.showMode == CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) { calendarProvider.expandStatus.addListener(() { setState(() { print( "calendarProvider.expandStatus.value:${calendarProvider.expandStatus.value}"); expand = calendarProvider.expandStatus.value; if (expand) { index = 0; //周视图切换到月视图 calendarProvider.calendarConfiguration!.weekController! .jumpToPage(calendarProvider.monthPageIndex); } else { index = 1; //月视图切换到周视图 calendarProvider.calendarConfiguration!.weekController! .jumpToPage(calendarProvider.weekPageIndex); } }); }); } else { index = 0; } widget.calendarController.addMonthChangeListener((year, month) { if (widget.calendarController.calendarProvider.calendarConfiguration! .showMode != CalendarConstants.MODE_SHOW_ONLY_WEEK) { //月份切换的时候,如果高度发生变化的话,需要setState使高度整体自适应 int lineCount = DateUtil.getMonthViewLineCount(year!, month!, widget.calendarController.calendarConfiguration.offset); double newHeight = itemHeight! * (lineCount) + calendarProvider.calendarConfiguration!.verticalSpacing! * (lineCount - 1); LogUtil.log( TAG: this.runtimeType, message: "totalHeight:$totalHeight,newHeight:$newHeight"); if (totalHeight!.toInt() != newHeight.toInt()) { LogUtil.log(TAG: this.runtimeType, message: "月份视图高度发生变化"); setState(() { totalHeight = newHeight; }); } } }); itemHeight = calendarProvider.calendarConfiguration!.itemSize; totalHeight = calendarProvider.totalHeight; } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { LogUtil.log(TAG: this.runtimeType, message: "CalendarContainerState build"); return Container( width: itemHeight! * 7, child: new Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ /** * 利用const,避免每次setState都会刷新到这顶部的view */ calendarProvider.calendarConfiguration!.weekBarItemWidgetBuilder!(), AnimatedContainer( duration: Duration(milliseconds: 500), height: expand ? totalHeight : itemHeight, child: IndexedStack( index: index, children: widgets, )), ], ), ); } }