|
@@ -0,0 +1,151 @@
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+import 'calendar_utils.dart' show get2Weekdays, addDay, subtractDay, firstDayOfWeek;
|
|
|
+import 'day_table_view.dart';
|
|
|
+
|
|
|
+enum PageState {
|
|
|
+ previous,
|
|
|
+ current,
|
|
|
+ next,
|
|
|
+}
|
|
|
+
|
|
|
+/// 一周的Days的PageView页面
|
|
|
+class WeekPage extends StatefulWidget {
|
|
|
+ const WeekPage({
|
|
|
+ super.key,
|
|
|
+ required this.selectedDate,
|
|
|
+ required this.now,
|
|
|
+ required this.isAutoSelect,
|
|
|
+ this.onChangedSelectedDate,
|
|
|
+ this.onChangedPage,
|
|
|
+ });
|
|
|
+
|
|
|
+ final DateTime now;
|
|
|
+ final DateTime selectedDate;
|
|
|
+ final bool isAutoSelect;
|
|
|
+
|
|
|
+ final Function(DateTime)? onChangedSelectedDate; //选择日期变化的监听
|
|
|
+ final Function(DateTime date, PageState state)? onChangedPage; //切换日期Page的监听
|
|
|
+
|
|
|
+ final double height = 40 + 40 + 10;
|
|
|
+
|
|
|
+ @override
|
|
|
+ State<StatefulWidget> createState() => _WeekPageState();
|
|
|
+}
|
|
|
+
|
|
|
+class _WeekPageState extends State<WeekPage> {
|
|
|
+ double get height => widget.height;
|
|
|
+ final int initialPage = 999;
|
|
|
+ List<int> pageCounts = [0, 1, 2];
|
|
|
+ int currentPage = 1;
|
|
|
+ late DateTime _currentPageDate;
|
|
|
+ late DateTime _slectedDate;
|
|
|
+
|
|
|
+ DateTime get now => widget.now;
|
|
|
+
|
|
|
+ DateTime get selectedDate => widget.selectedDate;
|
|
|
+
|
|
|
+ @override
|
|
|
+ void initState() {
|
|
|
+ super.initState();
|
|
|
+ _currentPageDate = selectedDate;
|
|
|
+ _slectedDate = selectedDate;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return Flexible(
|
|
|
+ child: AnimatedSize(
|
|
|
+ duration: const Duration(milliseconds: 250),
|
|
|
+ curve: Curves.easeInOut,
|
|
|
+ alignment: Alignment.topCenter,
|
|
|
+ child: SizedBox(
|
|
|
+ height: height,
|
|
|
+ child: pageViewBuilder(),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ //PageView的方式展示不同的星期,每周每一个Page
|
|
|
+ Widget pageViewBuilder() {
|
|
|
+ final PageController pageController = PageController(initialPage: initialPage);
|
|
|
+ return PageView.builder(
|
|
|
+ itemBuilder: (context, index) {
|
|
|
+ final idx = _getIndex(index);
|
|
|
+ return dayTable(idx);
|
|
|
+ },
|
|
|
+ onPageChanged: onPageChanged,
|
|
|
+ controller: pageController,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ //两周的数据
|
|
|
+ Widget dayTable(int index) {
|
|
|
+ int at = pageCounts[index] - 1;
|
|
|
+ final weekdays = get2Weekdays(now, at);
|
|
|
+ return DayTableView(
|
|
|
+ weekdays: weekdays,
|
|
|
+ onSelect: (date) {
|
|
|
+ setState(() {
|
|
|
+ _slectedDate = date;
|
|
|
+ });
|
|
|
+ //主动点击之后回调
|
|
|
+ widget.onChangedSelectedDate?.call(date);
|
|
|
+ },
|
|
|
+ selectedDate: _slectedDate,
|
|
|
+ currentDate: now,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ //是否需要切换页面的时候自动选中
|
|
|
+ void changeSelectedDate(int value) {
|
|
|
+ if (_pageState(value) == PageState.next) {
|
|
|
+ if (widget.isAutoSelect) {
|
|
|
+ _slectedDate = addDay(selectedDate, 14);
|
|
|
+ widget.onChangedSelectedDate?.call(_slectedDate);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (widget.isAutoSelect) {
|
|
|
+ _slectedDate = subtractDay(selectedDate, 14);
|
|
|
+ widget.onChangedSelectedDate?.call(_slectedDate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //当切换页面的时候更新当前页面数据,返回当前页面第一条数据的日期
|
|
|
+ void updateCurrentPageDate(int value) {
|
|
|
+ final first = firstDayOfWeek(_currentPageDate);
|
|
|
+
|
|
|
+ if (_pageState(value) == PageState.next) {
|
|
|
+ _currentPageDate = addDay(first, 14);
|
|
|
+ widget.onChangedPage?.call(_currentPageDate, PageState.next);
|
|
|
+ } else {
|
|
|
+ _currentPageDate = subtractDay(first, 14);
|
|
|
+ widget.onChangedPage?.call(_currentPageDate, PageState.previous);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void onPageChanged(int value) {
|
|
|
+ changeSelectedDate(value);
|
|
|
+ updateCurrentPageDate(value);
|
|
|
+
|
|
|
+ int currentIndex = _getIndex(value);
|
|
|
+ int leftIndex = (currentIndex - 1 < 0) ? pageCounts.length - 1 : currentIndex - 1;
|
|
|
+ int rightIndex = (currentIndex + 1 > pageCounts.length - 1) ? 0 : currentIndex + 1;
|
|
|
+
|
|
|
+ pageCounts[leftIndex] = pageCounts[currentIndex] - 1;
|
|
|
+ pageCounts[rightIndex] = pageCounts[currentIndex] + 1;
|
|
|
+
|
|
|
+ currentPage = pageCounts[currentIndex];
|
|
|
+ }
|
|
|
+
|
|
|
+ int _getIndex(int idx) {
|
|
|
+ return (idx + 1) % pageCounts.length;
|
|
|
+ }
|
|
|
+
|
|
|
+ PageState _pageState(int idx) {
|
|
|
+ final prePage = currentPage;
|
|
|
+ final current = pageCounts[_getIndex(idx)];
|
|
|
+ return (prePage < current) ? PageState.next : PageState.previous;
|
|
|
+ }
|
|
|
+}
|