Skip to content

Commit 4b104af

Browse files
committed
refactor(calendar): better calendar view
Closes #72
1 parent d7ce571 commit 4b104af

File tree

3 files changed

+245
-126
lines changed

3 files changed

+245
-126
lines changed
Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,56 @@
1-
import 'package:flutter/widgets.dart';
1+
import 'package:flutter/material.dart';
22
import 'package:get/get.dart';
3+
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
34

45
import '../../../utils/data/isar.dart';
56
import 'calendar_state.dart';
67

78
class CalendarLogic extends GetxController {
89
final CalendarState state = CalendarState();
910

11+
late final ItemScrollController itemScrollController = ItemScrollController();
12+
late final ScrollOffsetController scrollOffsetController = ScrollOffsetController();
13+
late final ItemPositionsListener itemPositionsListener = ItemPositionsListener.create();
14+
late final ScrollOffsetListener scrollOffsetListener = ScrollOffsetListener.create();
15+
16+
late final ExpansionTileController expansionTileController = ExpansionTileController();
17+
1018
@override
1119
void onReady() async {
1220
await getMonthDiary(state.currentMonth.value);
21+
1322
super.onReady();
1423
}
1524

25+
@override
26+
void onClose() {
27+
super.onClose();
28+
}
29+
1630
// 获取当前月份的日记
1731
Future<void> getMonthDiary(DateTime value) async {
1832
state.isFetching.value = true;
19-
final diaryList = await IsarUtil.getDiaryByMonth(value.year, value.month);
20-
var dateWithDiaryList = <DateTime>[];
21-
// 获取有日记的日期,只需要年月日
22-
for (var diary in diaryList) {
23-
// 如果不存在当前日期,则添加
24-
var time = diary.time;
25-
if (!dateWithDiaryList.contains(DateTime(time.year, time.month, time.day))) {
26-
dateWithDiaryList.add(DateTime(time.year, time.month, time.day));
27-
}
28-
}
29-
state.selectedDate.value = DateTime.now();
30-
state.currentMonthDiaryMap = {for (var e in diaryList) e: GlobalKey()};
31-
update();
33+
state.currentMonth.value = value;
34+
state.currentMonthDiaryList.value = await IsarUtil.getDiaryByMonth(value.year, value.month);
3235
state.isFetching.value = false;
3336
}
3437

35-
// 选中日期后滚动到该日期
36-
Future<void> animateToSelectedDate(DateTime value) async {
37-
state.selectedDate.value = value;
38-
// 根据日期找到当前列表中第一篇日记对应的 GlobalKey,然后滚动到该日记
39-
var key = state.currentMonthDiaryMap.entries
40-
.firstWhere((element) =>
41-
element.key.yMd == '${value.year.toString()}/${value.month.toString()}/${value.day.toString()}')
42-
.value;
43-
Scrollable.ensureVisible(key.currentContext!, duration: Duration(milliseconds: 300));
38+
int _pendingScrollOperations = 0;
39+
40+
Future<void> animateToSelectedDateWithLock(DateTime value) async {
41+
final index =
42+
state.currentMonthDiaryList.indexWhere((element) => element.yMd == '${value.year}/${value.month}/${value.day}');
43+
_pendingScrollOperations++;
44+
state.isControllerScrolling.value = true;
45+
try {
46+
await itemScrollController.scrollTo(
47+
index: index, duration: const Duration(seconds: 1), curve: Curves.easeInOutQuart);
48+
} finally {
49+
_pendingScrollOperations--;
50+
if (_pendingScrollOperations == 0) {
51+
state.isControllerScrolling.value = false;
52+
}
53+
}
4454
}
4555

4656
// // 选中日期后重新获取日记
@@ -50,6 +60,10 @@ class CalendarLogic extends GetxController {
5060
// }
5161

5262
void open(value) {
53-
state.isExpanded.value = value;
63+
if (value && !expansionTileController.isExpanded) {
64+
expansionTileController.expand();
65+
} else if (!value && expansionTileController.isExpanded) {
66+
expansionTileController.collapse();
67+
}
5468
}
5569
}
Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,15 @@
1-
import 'package:flutter/widgets.dart';
21
import 'package:get/get.dart';
32
import 'package:mood_diary/common/models/isar/diary.dart';
43

54
class CalendarState {
6-
//选中的时间
7-
late Rx<DateTime> selectedDate;
8-
9-
late Rx<DateTime> currentMonth;
5+
late Rx<DateTime> currentMonth = DateTime.now().obs;
106

117
//当前月份的日记
12-
late Map<Diary, GlobalKey> currentMonthDiaryMap = {};
13-
14-
late RxBool isExpanded;
8+
late RxList<Diary> currentMonthDiaryList = <Diary>[].obs;
159

1610
late RxBool isFetching = true.obs;
1711

18-
CalendarState() {
19-
//默认是今天
20-
var now = DateTime.now();
21-
selectedDate = now.obs;
22-
currentMonth = now.obs;
23-
isExpanded = false.obs;
12+
late RxBool isControllerScrolling = false.obs;
2413

25-
///Initialize variables
26-
}
14+
CalendarState();
2715
}

0 commit comments

Comments
 (0)