1
- import 'package:flutter/widgets .dart' ;
1
+ import 'package:flutter/material .dart' ;
2
2
import 'package:get/get.dart' ;
3
+ import 'package:scrollable_positioned_list/scrollable_positioned_list.dart' ;
3
4
4
5
import '../../../utils/data/isar.dart' ;
5
6
import 'calendar_state.dart' ;
6
7
7
8
class CalendarLogic extends GetxController {
8
9
final CalendarState state = CalendarState ();
9
10
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
+
10
18
@override
11
19
void onReady () async {
12
20
await getMonthDiary (state.currentMonth.value);
21
+
13
22
super .onReady ();
14
23
}
15
24
25
+ @override
26
+ void onClose () {
27
+ super .onClose ();
28
+ }
29
+
16
30
// 获取当前月份的日记
17
31
Future <void > getMonthDiary (DateTime value) async {
18
32
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);
32
35
state.isFetching.value = false ;
33
36
}
34
37
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
+ }
44
54
}
45
55
46
56
// // 选中日期后重新获取日记
@@ -50,6 +60,10 @@ class CalendarLogic extends GetxController {
50
60
// }
51
61
52
62
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
+ }
54
68
}
55
69
}
0 commit comments