Merge pull request #54 from msidolphin/feat/day_offset

feat: 支持设置首日偏移量
master
LXD312569496 5 years ago committed by GitHub
commit 47fcb6c67b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -74,7 +74,8 @@
Set<DateTime> selectedDateTimeList = EMPTY_SET, Set<DateTime> selectedDateTimeList = EMPTY_SET,
DateModel selectDateModel, DateModel selectDateModel,
int maxMultiSelectCount = 9999, int maxMultiSelectCount = 9999,
Map<DateModel, Object> extraDataMap = EMPTY_MAP}) Map<DateModel, Object> extraDataMap = EMPTY_MAP,
int offset = 0})
``` ```
#### 通用参数说明 #### 通用参数说明
@ -94,11 +95,12 @@
| minSelectDay | 可以选择的最小月份的日子 | 1 | | minSelectDay | 可以选择的最小月份的日子 | 1 |
| maxSelectYear | 可以选择的最大年份 | 2055 | | maxSelectYear | 可以选择的最大年份 | 2055 |
| maxSelectMonth | 可以选择的最大年份的月份 | 12 | | maxSelectMonth | 可以选择的最大年份的月份 | 12 |
| maxSelectDay | 可以选择的最大月份的日子 | 30注意不能超过对应月份的总天数 | | maxSelectDay | 可以选择的最大月份的日子 | 30注意不能超过对应月份的总天数 |
| selectedDateList | 被选中的日期,用于多选 | 默认为空Set, Set<DateModel> selectedDateList = new Set() | | selectedDateList | 被选中的日期,用于多选 | 默认为空Set, Set<DateModel> selectedDateList = new Set() |
| selectDateModel | 当前选择项,用于单选 | 默认为空 | | selectDateModel | 当前选择项,用于单选 | 默认为空 |
| maxMultiSelectCount | 多选,最多选多少个 | hhh | | maxMultiSelectCount | 多选,最多选多少个 | hhh |
| extraDataMap | 自定义额外的数据 | 默认为空MapMap<DateTime, Object> extraDataMap = new Map() | | extraDataMap | 自定义额外的数据 | 默认为空MapMap<DateTime, Object> extraDataMap = new Map() |
| offset | 首日偏移量 | 0 |
#### 给controller添加事件监听 #### 给controller添加事件监听

@ -73,7 +73,8 @@ One is to use the controller to add event monitoring and use the controller to o
Set<DateTime> selectedDateTimeList = EMPTY_SET, Set<DateTime> selectedDateTimeList = EMPTY_SET,
DateModel selectDateModel, DateModel selectDateModel,
int maxMultiSelectCount = 9999, int maxMultiSelectCount = 9999,
Map<DateModel, Object> extraDataMap = EMPTY_MAP}) Map<DateModel, Object> extraDataMap = EMPTY_MAP,
int offset})
``` ```
#### General parameter description #### General parameter description
@ -98,6 +99,7 @@ One is to use the controller to add event monitoring and use the controller to o
| selectDateModel | Current selection, for radio selection | 默认为空 | | selectDateModel | Current selection, for radio selection | 默认为空 |
| maxMultiSelectCount | Multiple choice, how many at most | hhh | | maxMultiSelectCount | Multiple choice, how many at most | hhh |
| extraDataMap | Customize additional data | 默认为空MapMap<DateTime, Object> extraDataMap = new Map() | | extraDataMap | Customize additional data | 默认为空MapMap<DateTime, Object> extraDataMap = new Map() |
| offset | The offset of first day | 0 |
#### Add event listening to controller #### Add event listening to controller

@ -0,0 +1,192 @@
import 'package:flutter/material.dart';
import 'package:flutter_custom_calendar/flutter_custom_calendar.dart';
/**
* +
*/
class CustomOffsetPage extends StatefulWidget {
CustomOffsetPage({Key key, this.title}) : super(key: key);
final String title;
@override
_CustomOffsetPageState createState() => _CustomOffsetPageState();
}
class _CustomOffsetPageState extends State<CustomOffsetPage> {
ValueNotifier<String> text;
ValueNotifier<String> selectText;
CalendarController controller;
@override
void initState() {
super.initState();
controller = new CalendarController(
offset: 5
);
controller.addMonthChangeListener(
(year, month) {
text.value = "$year$month";
},
);
controller.addOnCalendarSelectListener((dateModel) {
//
selectText.value =
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}";
});
text = new ValueNotifier("${DateTime.now().year}${DateTime.now().month}");
selectText = new ValueNotifier(
"单选模式\n选中的时间:\n${controller.getSingleSelectCalendar()}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new IconButton(
icon: Icon(Icons.navigate_before),
onPressed: () {
controller.moveToPreviousMonth();
}),
ValueListenableBuilder(
valueListenable: text,
builder: (context, value, child) {
return new Text(text.value);
}),
new IconButton(
icon: Icon(Icons.navigate_next),
onPressed: () {
controller.moveToNextMonth();
}),
],
),
CalendarViewWidget(
calendarController: controller,
weekBarItemWidgetBuilder: () {
return CustomStyleWeekBarItem();
},
dayWidgetBuilder: (dateModel) {
return CustomStyleDayWidget(dateModel);
}
),
ValueListenableBuilder(
valueListenable: selectText,
builder: (context, value, child) {
return new Text(selectText.value);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class CustomStyleWeekBarItem extends BaseWeekBar {
final List<String> weekList = ["", "", "", "", "", "", ""];
@override
Widget getWeekBarItem(int index) {
return new Container(
child: new Center(
child: new Text(weekList[index]),
),
);
}
}
class CustomStyleDayWidget extends BaseCustomDayWidget {
CustomStyleDayWidget(DateModel dateModel) : super(dateModel);
@override
void drawNormal(DateModel dateModel, Canvas canvas, Size size) {
// if (!dateModel.isCurrentMonth) {
// return;
// }
bool isWeekend = dateModel.isWeekend;
bool isInRange = dateModel.isInRange;
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(
color: !isInRange
? Colors.grey
: isWeekend ? Colors.blue : Colors.black,
fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(
color: !isInRange
? Colors.grey
: isWeekend ? Colors.blue : Colors.grey,
fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
@override
void drawSelected(DateModel dateModel, Canvas canvas, Size size) {
// if (!dateModel.isCurrentMonth) {
// return;
// }
//
Paint backGroundPaint = new Paint()
..color = Colors.blue
..strokeWidth = 2;
double padding = 8;
canvas.drawCircle(Offset(size.width / 2, size.height / 2),
(size.width - padding) / 2, backGroundPaint);
//
TextPainter dayTextPainter = new TextPainter()
..text = TextSpan(
text: dateModel.day.toString(),
style: new TextStyle(color: Colors.white, fontSize: 16))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
dayTextPainter.layout(minWidth: size.width, maxWidth: size.width);
dayTextPainter.paint(canvas, Offset(0, 10));
//
TextPainter lunarTextPainter = new TextPainter()
..text = new TextSpan(
text: dateModel.lunarString,
style: new TextStyle(color: Colors.white, fontSize: 12))
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center;
lunarTextPainter.layout(minWidth: size.width, maxWidth: size.width);
lunarTextPainter.paint(canvas, Offset(0, size.height / 2));
}
}

@ -1,3 +1,5 @@
import 'package:example1/custom_offset_page.dart';
import 'only_week_page.dart'; import 'only_week_page.dart';
import 'red_style_page.dart'; import 'red_style_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -42,6 +44,7 @@ class MyApp extends StatelessWidget {
), ),
"/blue_style_page": (context) => BlueStylePage(title: "蓝色背景Demo"), "/blue_style_page": (context) => BlueStylePage(title: "蓝色背景Demo"),
"/red_style_page": (context) => RedStylePage(title: "蓝色背景Demo"), "/red_style_page": (context) => RedStylePage(title: "蓝色背景Demo"),
"/custom_offset_page": (context) => CustomOffsetPage(title: "自定义偏移量"),
}, },
title: 'Flutter Demo', title: 'Flutter Demo',
theme: ThemeData( theme: ThemeData(
@ -105,6 +108,12 @@ class HomePage extends StatelessWidget {
Navigator.pushNamed(context, "/red_style_page"); Navigator.pushNamed(context, "/red_style_page");
}, },
child: new Text("红色Demo"), child: new Text("红色Demo"),
),
new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "/custom_offset_page");
},
child: new Text("自定义偏移量"),
) )
], ],
), ),

@ -173,7 +173,7 @@ class CalendarProvider extends ChangeNotifier {
calendarConfiguration.showMode == calendarConfiguration.showMode ==
CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) { CalendarConstants.MODE_SHOW_MONTH_AND_WEEK) {
int lineCount = DateUtil.getMonthViewLineCount( int lineCount = DateUtil.getMonthViewLineCount(
calendarConfiguration.nowYear, calendarConfiguration.nowMonth); calendarConfiguration.nowYear, calendarConfiguration.nowMonth, calendarConfiguration.offset);
totalHeight = calendarConfiguration.itemSize * (lineCount) + totalHeight = calendarConfiguration.itemSize * (lineCount) +
calendarConfiguration.verticalSpacing * (lineCount - 1); calendarConfiguration.verticalSpacing * (lineCount - 1);
} else { } else {

@ -78,6 +78,10 @@ class CalendarConfiguration {
DateModel minSelectDate; DateModel minSelectDate;
DateModel maxSelectDate; DateModel maxSelectDate;
/// first day offset
/// first day = (first day of month or week) + offset
final int offset;
CalendarConfiguration( CalendarConfiguration(
{this.selectMode, {this.selectMode,
this.minYear, this.minYear,
@ -104,7 +108,8 @@ class CalendarConfiguration {
this.itemSize, this.itemSize,
this.showMode, this.showMode,
this.padding, this.padding,
this.margin}); this.margin,
this.offset = 0});
@override @override
String toString() { String toString() {

@ -50,7 +50,10 @@ class CalendarController {
Set<DateTime> selectedDateTimeList = EMPTY_SET, //item Set<DateTime> selectedDateTimeList = EMPTY_SET, //item
DateModel selectDateModel, //item DateModel selectDateModel, //item
int maxMultiSelectCount = 9999, int maxMultiSelectCount = 9999,
Map<DateModel, Object> extraDataMap = EMPTY_MAP}) { Map<DateModel, Object> extraDataMap = EMPTY_MAP,
int offset = 0 //
}) {
assert(offset >= 0 && offset <= 6);
LogUtil.log(TAG: this.runtimeType, message: "init CalendarConfiguration"); LogUtil.log(TAG: this.runtimeType, message: "init CalendarConfiguration");
// //
if (nowYear == null) { if (nowYear == null) {
@ -76,7 +79,8 @@ class CalendarController {
extraDataMap: extraDataMap, extraDataMap: extraDataMap,
maxSelectDay: maxSelectDay, maxSelectDay: maxSelectDay,
maxMultiSelectCount: maxMultiSelectCount, maxMultiSelectCount: maxMultiSelectCount,
selectDateModel: selectDateModel); selectDateModel: selectDateModel,
offset: offset);
calendarConfiguration.defaultSelectedDateList = new HashSet<DateModel>(); calendarConfiguration.defaultSelectedDateList = new HashSet<DateModel>();
calendarConfiguration.defaultSelectedDateList calendarConfiguration.defaultSelectedDateList

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_custom_calendar/model/date_model.dart'; import 'package:flutter_custom_calendar/model/date_model.dart';
import 'package:flutter_custom_calendar/utils/LogUtil.dart'; import 'package:flutter_custom_calendar/utils/LogUtil.dart';
@ -99,10 +100,10 @@ class DateUtil {
* ,1 * ,1
* @return the start diff with MonthView * @return the start diff with MonthView
*/ */
static int getIndexOfFirstDayInMonth(DateTime dateTime) { static int getIndexOfFirstDayInMonth(DateTime dateTime, {int offset = 0}) {
DateTime firstDayOfMonth = new DateTime(dateTime.year, dateTime.month, 1); DateTime firstDayOfMonth = new DateTime(dateTime.year, dateTime.month, 1);
int week = firstDayOfMonth.weekday; int week = firstDayOfMonth.weekday + offset;
return week; return week;
} }
@ -111,11 +112,12 @@ class DateUtil {
int year, int month, DateTime currentDate, int weekStart, int year, int month, DateTime currentDate, int weekStart,
{DateModel minSelectDate, {DateModel minSelectDate,
DateModel maxSelectDate, DateModel maxSelectDate,
Map<DateModel, Object> extraDataMap}) { Map<DateModel, Object> extraDataMap,
int offset = 0}) {
print('initCalendarForMonthView start'); print('initCalendarForMonthView start');
weekStart = DateTime.monday; weekStart = DateTime.monday;
// //
int mPreDiff = getIndexOfFirstDayInMonth(new DateTime(year, month)); int mPreDiff = getIndexOfFirstDayInMonth(new DateTime(year, month), offset: offset);
// //
int monthDayCount = getMonthDaysCount(year, month); int monthDayCount = getMonthDaysCount(year, month);
@ -136,6 +138,10 @@ class DateUtil {
DateTime temp; DateTime temp;
DateModel dateModel; DateModel dateModel;
if (i < mPreDiff - 1) { if (i < mPreDiff - 1) {
if (i < ((mPreDiff / 7).ceil() - 1) * 7) {
size++;
continue;
}
// //
temp = firstDayOfMonth.subtract(Duration(days: mPreDiff - i - 1)); temp = firstDayOfMonth.subtract(Duration(days: mPreDiff - i - 1));
@ -183,19 +189,18 @@ class DateUtil {
/** /**
* *
*/ */
static int getMonthViewLineCount(int year, int month) { static int getMonthViewLineCount(int year, int month, int offset) {
DateTime firstDayOfMonth = new DateTime(year, month, 1); DateTime firstDayOfMonth = new DateTime(year, month, 1);
int monthDayCount = getMonthDaysCount(year, month); int monthDayCount = getMonthDaysCount(year, month);
// DateTime lastDayOfMonth = new DateTime(year, month, monthDayCount);
int preIndex = firstDayOfMonth.weekday - 1;
// int lastIndex = lastDayOfMonth.weekday;
int preIndex = (firstDayOfMonth.weekday - 1 + offset) % 7;
int lineCount = ((preIndex + monthDayCount) / 7).ceil();
LogUtil.log( LogUtil.log(
TAG: "DateUtil", TAG: "DateUtil",
message: message:
"getMonthViewLineCount:$year$month月:有${((preIndex + monthDayCount) / 7).toInt() + 1}"); "getMonthViewLineCount:$year$month月:有$lineCount");
return ((preIndex + monthDayCount) / 7).toInt() + 1;
return lineCount;
} }
/** /**
@ -205,10 +210,11 @@ class DateUtil {
int year, int month, DateTime currentDate, int weekStart, int year, int month, DateTime currentDate, int weekStart,
{DateModel minSelectDate, {DateModel minSelectDate,
DateModel maxSelectDate, DateModel maxSelectDate,
Map<DateModel, Object> extraDataMap}) { Map<DateModel, Object> extraDataMap,
int offset = 0}) {
List<DateModel> items = List(); List<DateModel> items = List();
int weekDay = currentDate.weekday; int weekDay = currentDate.weekday + offset;
// //
DateTime firstDayOfWeek = currentDate.add(Duration(days: -weekDay)); DateTime firstDayOfWeek = currentDate.add(Duration(days: -weekDay));

@ -167,7 +167,7 @@ class CalendarContainerState extends State<CalendarContainer>
.showMode != .showMode !=
CalendarConstants.MODE_SHOW_ONLY_WEEK) { CalendarConstants.MODE_SHOW_ONLY_WEEK) {
//setState使 //setState使
int lineCount = DateUtil.getMonthViewLineCount(year, month); int lineCount = DateUtil.getMonthViewLineCount(year, month, widget.calendarController.calendarConfiguration.offset);
double newHeight = itemHeight * (lineCount) + double newHeight = itemHeight * (lineCount) +
calendarProvider.calendarConfiguration.verticalSpacing * calendarProvider.calendarConfiguration.verticalSpacing *
(lineCount - 1); (lineCount - 1);

@ -42,7 +42,6 @@ class _MonthViewState extends State<MonthView>
void initState() { void initState() {
super.initState(); super.initState();
extraDataMap = widget.configuration.extraDataMap; extraDataMap = widget.configuration.extraDataMap;
DateModel firstDayOfMonth = DateModel firstDayOfMonth =
DateModel.fromDateTime(DateTime(widget.year, widget.month, 1)); DateModel.fromDateTime(DateTime(widget.year, widget.month, 1));
if (CacheData.getInstance().monthListCache[firstDayOfMonth]?.isNotEmpty == if (CacheData.getInstance().monthListCache[firstDayOfMonth]?.isNotEmpty ==
@ -56,7 +55,7 @@ class _MonthViewState extends State<MonthView>
}); });
} }
lineCount = DateUtil.getMonthViewLineCount(widget.year, widget.month); lineCount = DateUtil.getMonthViewLineCount(widget.year, widget.month, widget.configuration.offset);
//,generation //,generation
WidgetsBinding.instance.addPostFrameCallback((callback) { WidgetsBinding.instance.addPostFrameCallback((callback) {
@ -75,7 +74,8 @@ class _MonthViewState extends State<MonthView>
'month': widget.month, 'month': widget.month,
'minSelectDate': widget.configuration.minSelectDate, 'minSelectDate': widget.configuration.minSelectDate,
'maxSelectDate': widget.configuration.maxSelectDate, 'maxSelectDate': widget.configuration.maxSelectDate,
'extraDataMap': extraDataMap 'extraDataMap': extraDataMap,
'offset': widget.configuration.offset
}); });
setState(() {}); setState(() {});
} }
@ -85,7 +85,8 @@ class _MonthViewState extends State<MonthView>
map['year'], map['month'], DateTime.now(), DateTime.sunday, map['year'], map['month'], DateTime.now(), DateTime.sunday,
minSelectDate: map['minSelectDate'], minSelectDate: map['minSelectDate'],
maxSelectDate: map['maxSelectDate'], maxSelectDate: map['maxSelectDate'],
extraDataMap: map['extraDataMap']); extraDataMap: map['extraDataMap'],
offset: map['offset']);
} }
@override @override
@ -104,7 +105,7 @@ class _MonthViewState extends State<MonthView>
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 7, mainAxisSpacing: configuration.verticalSpacing), crossAxisCount: 7, mainAxisSpacing: configuration.verticalSpacing),
itemCount: items.isEmpty ? 0 : 7 * lineCount, itemCount: items.isEmpty ? 0 : items.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
DateModel dateModel = items[index]; DateModel dateModel = items[index];
// //

@ -51,7 +51,8 @@ class _WeekViewState extends State<WeekView> {
widget.year, widget.month, widget.firstDayOfWeek.getDateTime(), 0, widget.year, widget.month, widget.firstDayOfWeek.getDateTime(), 0,
minSelectDate: widget.configuration.minSelectDate, minSelectDate: widget.configuration.minSelectDate,
maxSelectDate: widget.configuration.maxSelectDate, maxSelectDate: widget.configuration.maxSelectDate,
extraDataMap: extraDataMap); extraDataMap: extraDataMap,
offset: widget.configuration.offset);
setState(() {}); setState(() {});
}); });
}); });

Loading…
Cancel
Save