You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
flutter_custom_calendar/lib/controller.dart

337 lines
9.6 KiB

5 years ago
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/widget/default_combine_day_view.dart';
import 'package:flutter_custom_calendar/widget/default_custom_day_view.dart';
5 years ago
import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/widget/default_week_bar.dart';
5 years ago
import 'package:flutter_custom_calendar/constants/constants.dart';
/**
* controller
*/
class CalendarController {
static const Set<DateTime> EMPTY_SET = {};
static const Map<DateTime, Object> EMPTY_MAP = {};
//默认是单选,可以配置为MODE_SINGLE_SELECTMODE_MULTI_SELECT
int selectMode;
//展开状态
bool expandStatus;
ValueNotifier<bool> expandChanged;
5 years ago
//日历显示的最小年份和最大年份
int minYear;
int maxYear;
//日历显示的最小年份的月份,最大年份的月份
int minYearMonth;
int maxYearMonth;
//日历显示的当前的年份和月份
int nowYear;
int nowMonth;
//可操作的范围设置,比如点击选择
int minSelectYear;
int minSelectMonth;
int minSelectDay;
int maxSelectYear;
int maxSelectMonth;
int maxSelectDay; //注意:不能超过对应月份的总天数
Set<DateModel> selectedDateList = new Set(); //被选中的日期,用于多选
DateModel selectDateModel; //当前选择项,用于单选
int maxMultiSelectCount; //多选,最多选多少个
Map<DateTime, Object> extraDataMap = new Map(); //自定义额外的数据
//各种事件回调
OnMonthChange monthChange; //月份切换事件
OnCalendarSelect calendarSelect; //点击选择事件
OnMultiSelectOutOfRange multiSelectOutOfRange; //多选超出指定范围
OnMultiSelectOutOfSize multiSelectOutOfSize; //多选超出限制个数
//支持自定义绘制
DayWidgetBuilder dayWidgetBuilder; //创建日历item
WeekBarItemWidgetBuilder weekBarItemWidgetBuilder; //创建顶部的weekbar
/**
*
*/
List<DateModel> monthList = new List(); //月份list
List<DateModel> weekList=new List();//星期list
5 years ago
PageController pageController;
CalendarController(
{int selectMode = Constants.MODE_SINGLE_SELECT,
bool expandStatus = true,
5 years ago
DayWidgetBuilder dayWidgetBuilder = defaultCustomDayWidget,
WeekBarItemWidgetBuilder weekBarItemWidgetBuilder = defaultWeekBarWidget,
int minYear = 1971,
int maxYear = 2055,
int minYearMonth = 1,
int maxYearMonth = 12,
int nowYear = -1,
int nowMonth = -1,
int minSelectYear = 1971,
int minSelectMonth = 1,
int minSelectDay = 1,
int maxSelectYear = 2055,
int maxSelectMonth = 12,
int maxSelectDay = 30,
Set<DateTime> selectedDateTimeList = EMPTY_SET,
DateModel selectDateModel,
int maxMultiSelectCount = 9999,
Map<DateTime, Object> extraDataMap = EMPTY_MAP}) {
this.selectMode = selectMode;
this.minYear = minYear;
this.maxYear = maxYear;
this.minYearMonth = minYearMonth;
this.maxYearMonth = maxYearMonth;
this.nowYear = nowYear;
this.nowMonth = nowMonth;
this.minSelectYear = minSelectYear;
this.minSelectMonth = minSelectMonth;
this.minSelectDay = minSelectDay;
this.maxSelectYear = maxSelectYear;
this.maxSelectMonth = maxSelectMonth;
this.maxSelectDay = maxSelectDay;
this.selectDateModel = selectDateModel;
this.dayWidgetBuilder = dayWidgetBuilder;
this.weekBarItemWidgetBuilder = weekBarItemWidgetBuilder;
this.maxMultiSelectCount = maxMultiSelectCount;
this.extraDataMap = extraDataMap;
this.expandStatus = expandStatus;
this.expandChanged=ValueNotifier(expandStatus);
5 years ago
this.selectedDateList = Set();
if (selectedDateTimeList != null && selectedDateTimeList.isNotEmpty) {
this.selectedDateList.addAll(selectedDateTimeList.map((dateTime) {
return DateModel.fromDateTime(dateTime);
}).toSet());
}
//初始化pageController,initialPage默认是当前时间对于的页面
int initialPage;
int nowMonthIndex = 0;
monthList.clear();
for (int i = minYear; i <= maxYear; i++) {
for (int j = 1; j <= 12; j++) {
if (i == minYear && j < minYearMonth) {
continue;
}
if (i == maxYear && j > maxYearMonth) {
continue;
}
DateModel dateModel = new DateModel();
dateModel.year = i;
dateModel.month = j;
//如果没有配置当前时间,设置成当前的时间
if (nowYear == -1 || nowMonth == -1) {
nowYear = DateTime.now().year;
nowMonth = DateTime.now().month;
}
if (i == nowYear && j == nowMonth) {
initialPage = nowMonthIndex;
}
monthList.add(dateModel);
nowMonthIndex++;
}
}
this.pageController = new PageController(initialPage: initialPage);
}
//月份切换监听
void addMonthChangeListener(OnMonthChange listener) {
this.monthChange = listener;
}
//点击选择监听
void addOnCalendarSelectListener(OnCalendarSelect listener) {
this.calendarSelect = listener;
}
//多选超出指定范围
void addOnMultiSelectOutOfRangeListener(OnMultiSelectOutOfRange listener) {
this.multiSelectOutOfRange = listener;
}
//多选超出限制个数
void addOnMultiSelectOutOfSizeListener(OnMultiSelectOutOfSize listener) {
this.multiSelectOutOfSize = listener;
}
//跳转到指定日期
void moveToCalendar(int year, int month, int day,
{bool needAnimation = false,
Duration duration = const Duration(milliseconds: 500),
Curve curve = Curves.ease}) {
DateModel dateModel = DateModel.fromDateTime(DateTime(year, month, 1));
5 years ago
//计算目标索引
int targetPage = monthList.indexOf(dateModel);
if (targetPage == -1) {
return;
}
if (needAnimation) {
pageController.animateToPage(targetPage,
duration: duration, curve: curve);
} else {
pageController.jumpToPage(targetPage);
}
}
//切换到下一年
void moveToNextYear(
{bool needAnimation = false,
Duration duration = const Duration(milliseconds: 500),
Curve curve = Curves.ease}) {
DateTime targetDateTime =
monthList[pageController.page.toInt() + 12].getDateTime();
moveToCalendar(
targetDateTime.year, targetDateTime.month, targetDateTime.day,
needAnimation: needAnimation, duration: duration, curve: curve);
}
//切换到上一年
void moveToPreviousYear(
{bool needAnimation = false,
Duration duration = const Duration(milliseconds: 500),
Curve curve = Curves.ease}) {
DateTime targetDateTime =
monthList[pageController.page.toInt() - 12].getDateTime();
moveToCalendar(
targetDateTime.year, targetDateTime.month, targetDateTime.day,
needAnimation: needAnimation, duration: duration, curve: curve);
}
//切换到下一个月份,
void moveToNextMonth(
{bool needAnimation = false,
Duration duration = const Duration(milliseconds: 500),
Curve curve = Curves.ease}) {
DateTime targetDateTime =
monthList[pageController.page.toInt() + 1].getDateTime();
moveToCalendar(
targetDateTime.year, targetDateTime.month, targetDateTime.day,
needAnimation: needAnimation, duration: duration, curve: curve);
}
//切换到上一个月份
void moveToPreviousMonth(
{bool needAnimation = false,
Duration duration = const Duration(milliseconds: 500),
Curve curve = Curves.ease}) {
DateTime targetDateTime =
monthList[pageController.page.toInt() - 1].getDateTime();
moveToCalendar(
targetDateTime.year, targetDateTime.month, targetDateTime.day,
needAnimation: needAnimation, duration: duration, curve: curve);
}
// 获取当前的月份
DateModel getCurrentMonth() {
return monthList[pageController.page.toInt()];
}
//获取被选中的日期,多选
Set<DateModel> getMultiSelectCalendar() {
if (selectedDateList.isEmpty) {
return null;
}
return selectedDateList;
}
//获取被选中的日期,单选
DateModel getSingleSelectCalendar() {
if (selectDateModel == null) {
return null;
}
return selectDateModel;
}
//切换展开状态
void toggleExpandStatus(){
expandChanged.value=!expandChanged.value;
print("toggleExpandStatus${expandChanged.value}");
}
void addExpandChangeListener(){
}
5 years ago
}
/**
* weekBar
*/
Widget defaultWeekBarWidget() {
return DefaultWeekBar();
}
/**
* 使canvasitem
*/
Widget defaultCustomDayWidget(DateModel dateModel) {
return DefaultCustomDayWidget(
dateModel,
);
}
/**
* 使widgetitem
*/
Widget defaultCombineDayWidget(DateModel dateModel) {
return new DefaultCombineDayWidget(
dateModel,
);
}
/**
*
*/
bool defaultInRange(DateModel dateModel) {
return true;
}
/**
*
*/
typedef void OnMonthChange(int year, int month);
/**
*
*/
typedef void OnCalendarSelect(DateModel dateModel);
/**
*
*/
typedef void OnMultiSelectOutOfRange();
/**
*
*/
typedef void OnMultiSelectOutOfSize();
/**
* item
*/
typedef Widget DayWidgetBuilder(DateModel dateModel);
/**
*
*/
typedef bool CanClick(DateModel dateModel);
/**
* Item
*/
typedef void DrawDayWidget(DateModel dateModel, Canvas canvas, Size size);
/**
* weekBar
*/
typedef Widget WeekBarItemWidgetBuilder();