Flutter仿釘釘考勤日歷的示例代碼
本文主要介紹了Flutter仿釘釘考勤日歷的示例代碼,分享給大家,具體如下:
效果
原型
開發(fā)
1. 使用
// 考勤日歷 DatePickerDialog( initialDate: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2030), onDateChanged: onDateChanged, // 0:無狀態(tài),1:正??记? 2:異??记?,遲到,早退, // 若不滿一個(gè)月,日歷會自動(dòng)用0補(bǔ)滿一個(gè)月 checking: [ 0, 0, 1, 2, ], ),
DatePickerDialog是在存在與Flutter的material包中,F(xiàn)lutter自帶的日歷是以dialog形式存在的,本文將dialog改成StatefulWidget直接在頁面中,將多余東西去掉,直接在material/calendar_date_picker.dart中_DayPicker上進(jìn)行修改。
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原來沒有,是修改加上去的,主要是顯示當(dāng)天打卡狀態(tài),若打卡正常則在日期顯示下方顯示藍(lán)色小點(diǎn),若有異常則顯示橙色的點(diǎn),若沒有狀態(tài)就不顯示,checking則是使用DatePickerDialog傳入的,由于日歷從1開始,數(shù)組是從索引0開始的,所以使用checking[day - 1]才能準(zhǔn)確獲取某一日的打卡狀態(tài),day 則是日歷中某一月中所有日期。
3.設(shè)置星期標(biāo)題
修改后:
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,則每周從星期一開始。
4.補(bǔ)全每個(gè)月空白日期:
獲取指定月份有多少天
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日的偏移量,即每個(gè)月第一天是星期幾,若1號是星期3,因?yàn)槿諝v每周是從第一天開始的,所以第一周的星期的星期一,星期二為空白,需要補(bǔ)全上個(gè)月的倒數(shù)后兩天,所以還需要獲取上個(gè)月的最后兩天是哪兩天。
// 獲取日期偏移 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; } ... // 補(bǔ)全開始日期 int day = -dayOffset; while (day < daysInMonth) { day++; if (day < 1) { dayItems.add(Container( margin: EdgeInsets.all(4.0), alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // daysInPreMonth上個(gè)月的天數(shù)-本月日期偏移則可把本月開始缺失的日期補(bǔ)全 Text(localizations.formatDecimal(daysInPreMonth - day.abs()), style: TextStyle( fontSize: 14.0, color: Color(0xFF888888), fontWeight: FontWeight.bold)), Visibility( visible: false, child: Container( height: 6.0, width: 6.0, decoration: BoxDecoration( shape: BoxShape.circle, color: Color(0xFFFF8A21), ), ), ), ], ), )); } else { ... } ... } }
補(bǔ)全日歷結(jié)束日期,每個(gè)月最后一天若為星期日,則無需補(bǔ)全,若為星期五則把下個(gè)月的前兩天補(bǔ)在本月的星期六和星期日:
if ((daysInMonth + dayOffset) % 7 > 0) { // 計(jì)算需要補(bǔ)多少天,直接從1開始就好 int addNum = 7 - ((daysInMonth + dayOffset) % 7); for (int i = 1; i <= addNum; i++) { dayItems.add(Container( margin: EdgeInsets.all(4.0), alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(localizations.formatDecimal(i), style: TextStyle( fontSize: 14.0, color: Color(0xFF888888), fontWeight: FontWeight.bold)), Visibility( visible: false, child: Container( height: 6.0, width: 6.0, decoration: BoxDecoration( shape: BoxShape.circle, color: Color(0xFFFF8A21), ), ), ), ], ), )); } }
計(jì)算每個(gè)月從星期一開始展示可以展示幾行,即計(jì)算日歷高度,月份不同,高度不同,最少4行,最多6行,根據(jù)內(nèi)容動(dòng)態(tài)顯示不至于留大量空白
// 計(jì)算一個(gè)月有多少天 int daysInMonth = ChinaDateUtils.getDaysInMonth( widget.initialDate.year, widget.initialDate.month); // 計(jì)算每個(gè)月第一天的星期 int dayOffset = ChinaDateUtils.firstDayOffsets( widget.initialDate.year, widget.initialDate.month); // 計(jì)算用多少行展示所有日期 int row = ((daysInMonth + dayOffset) / 7).ceil();
修改這些內(nèi)容大概可以實(shí)現(xiàn)上述效果。
Demo地址:https://gitee.com/masshub/sign_in
到此這篇關(guān)于Flutter仿釘釘考勤日歷的示例代碼的文章就介紹到這了,更多相關(guān)Flutter仿釘釘考勤日歷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Flutter實(shí)現(xiàn)頁面切換后保持原頁面狀態(tài)的3種方法
- Flutter 超實(shí)用簡單菜單彈出框 PopupMenuButton功能
- flutter InkWell實(shí)現(xiàn)水波紋點(diǎn)擊效果
- 詳解Flutter WebView與JS互相調(diào)用簡易指南
- Flutter持久化存儲之?dāng)?shù)據(jù)庫存儲(sqflite)詳解
- Flutter中如何加載并預(yù)覽本地的html文件的方法
- flutter日期選擇器 flutter時(shí)間選擇器
- 詳解flutter之網(wǎng)絡(luò)請求dio,請求,攔截器簡單示例
- 你必須掌握在Flutter中添加資源文件的方法
- Flutter中ListView 的使用示例
相關(guān)文章
Android之自定義實(shí)現(xiàn)BaseAdapter(通用適配器三)
這篇文章主要為大家詳細(xì)介紹了Android之自定義實(shí)現(xiàn)BaseAdapter通用適配器第三篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12使用Android實(shí)現(xiàn)一個(gè)懸浮在軟鍵盤上的輸入欄
app開發(fā)中經(jīng)常會遇到一些輸入框要懸浮到軟鍵盤上方的需求,下面這篇文章主要給大家介紹了關(guān)于如何使用Android實(shí)現(xiàn)一個(gè)懸浮在軟鍵盤上的輸入欄的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04Android實(shí)現(xiàn)雅虎新聞?wù)虞d視差動(dòng)畫效果
這篇文章主要介紹了Android實(shí)現(xiàn)雅虎新聞?wù)虞d視差動(dòng)畫效果,通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08Android實(shí)現(xiàn)帶簽到贏積分功能的日歷
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)帶簽到贏積分功能的日歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android 實(shí)現(xiàn)密碼輸入框動(dòng)態(tài)明文/密文切換顯示效果
在項(xiàng)目中遇到需要提供給用戶一個(gè)密碼輸入框明文/密文切換顯示的需求,今天小編借腳本之家平臺給大家分享下Android 實(shí)現(xiàn)密碼輸入框動(dòng)態(tài)明文/密文切換顯示效果,需要的朋友參考下2017-01-01Android編程之DatePicker和TimePicke簡單時(shí)間監(jiān)聽用法分析
這篇文章主要介紹了Android編程之DatePicker和TimePicke簡單時(shí)間監(jiān)聽用法,結(jié)合具體實(shí)例形式分析了時(shí)間控件DatePicker和TimePicke布局與具體功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-02-02Android利用Java優(yōu)雅消除復(fù)雜條件表達(dá)式的方法
這篇文章主要介紹了Android利用Java優(yōu)雅消除復(fù)雜條件表達(dá)式,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值。感興趣的小伙伴可以參考一下2022-06-06