Flutter 仿钉钉考勤日历,html5 移动端
// 考勤日历 DatePickerDialog(initialDate: DateTime.now(),firstDate: DateTime(2020),lastDate: DateTime(2030),onDateChanged: onDateChanged,// 0:无状态,1:正常考勤 2:异常考情,迟到,早退,// 若不满一个月,日历会自动用 0 补满一个月 checking: [0,0,1,2,],),
DatePickerDialog 是在存在与 Flutter 的 material 包中,Flutter 自带的日历是以 dialog 形式存在的,本文将 dialog 改成 StatefulWidget 直接在页面中,将多余东西去掉,直接在 material/calendar_date_picker.dart 中_DayPicker 上进行修改。 2. 修改日历中日期样式:
Widget dayWidget = Container(margin: EdgeInsets.all(4.0),decoration: decoration,alignment: Alignment.center,child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text(localizations.formatDecimal(day),style: TextStyle(fontSize: 14.0,color: dayColor,fontWeight: FontWeight.bold)),Visibility(visible: checking[day - 1] == 1 || checking[day - 1] == 2,child: Container(height: 6.0,width: 6.0,decoration: BoxDecoration(shape: BoxShape.circle,color: isSelectedDay ? Colors.white :(checking[day - 1] == 1 ? Color(0xFF1376EE): Color(0xFFFF8A21)),),),),],),);
Visibility 原来没有,是修改加上去的,主要是显示当天打卡状态,若打卡正常则在日期显示下方显示蓝色小点,若有异常则显示橙色的点,若没
有状态就不显示,checking 则是使用 DatePickerDialog 传入的,由于日历从 1 开始,数组是从索引 0 开始的,所以使用 checking[day - 1]才能准确获取某一日的打卡状态,day 则是日历中某一月中所有日期。
2.设置星期标题 修改后:
List<Widget> _dayHeaders() {final List<Widget> result = <Widget>[];final List<String> weekdays = ["日", "一", "二", "三", "四", "五", "六"];for (int i = 1; true; i = (i + 1) % 7) {final String weekday = weekdays[i];result.add(ExcludeSemantics(child: Center(child: Text(weekday,style: TextStyle(fontSize: 14.0, color: Color(0xFF999999)))),));if (i == (1 - 1) % 7) break;}return result;}
原文:
List<Widget> _dayHeaders(TextStyle? headerStyle, MaterialLocalizations localizations) {final List<Widget> result = <Widget>[];for (int i = localizations.firstDayOfWeekIndex; true; i = (i + 1) % 7) {final String weekday = localizations.narrowWeekdays[i];result.add(ExcludeSemantics(child: Center(child: Text(weekday, style: headerStyle)),));if (i == (localizations.firstDayOfWeekIndex - 1) % 7)break;}return result;}
localizations.firstDayOfWeekIndex 返回值为 0 或者 1,若返回 0,则星期日为每周的第一天;若返回 1,则星期一为每周的第一天。本文中没有从 localizations.firstDayOfWeekIndex 获取,直接赋值为 1,则每周从星期一开始。
3.补全每个月空白日期:
获取指定月份有多少天
static int getDaysInMonth(int year, int month) {if(month < 1){year = year - 1;month = month + 12;}
if(month > 12){year = year + 1;month = month - 12;}if (month == DateTime.february) {final bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);return isLeapYear ? 29 : 28;}const List<int> daysInMonth = <int>[31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];return daysInMonth[month - 1];}
获取指定月份 1 日的偏移量,即每个月第一天是星期几,若 1 号是星期 3,因为日历每周是从第一天开始的,所以第一周的星期的星期一,星期二为空白,需要补全上个月的倒数后两天,所以还需要获取上个月的最后两天是哪两天。
// 获取日期偏移 static int firstDayOffsets(int year, int month) {final int weekdayFromMonday = DateTime(year, month).weekday - 1;int firstDayOfWeekIndex = 1;firstDayOfWeekIndex = (firstDayOfWeekIndex - 1) % 7;return (weekdayFromMonday - firstDayOfWeekIndex) % 7;}...// 补全开始日期 int day = -dayOffset;while (day < daysInMonth) {day++;if (day < 1) {dayItems.add(Container(margin: EdgeInsets.all(4.0),alignment: Alignment.center,
评论