@@ -20,26 +20,36 @@ See the License for the specific language governing permissions and
20
20
limitations under the License.
21
21
*/
22
22
23
+ import 'dart:developer' ;
23
24
import 'dart:io' ;
24
25
25
26
import 'package:flutter/material.dart' ;
27
+ import 'package:watermeter/page/classtable/class_table_view/class_table_view.dart' ;
26
28
import 'package:watermeter/page/classtable/classtable_constant.dart' ;
27
29
import 'package:watermeter/page/classtable/classtable_state.dart' ;
28
30
import 'package:watermeter/page/classtable/not_arranged_class_list.dart' ;
29
- import 'package:watermeter/page/classtable/classtable_page_view.dart' ;
30
- import 'package:watermeter/page/classtable/week_choice_row.dart' ;
31
+ import 'package:watermeter/page/classtable/week_choice_button.dart' ;
31
32
import 'package:watermeter/repository/network_session.dart' ;
32
33
import 'package:watermeter/repository/preference.dart' as preference;
33
34
34
- /// The [ClassTablePage] contains [WeekChoiceRow] and [ClassTablePageView] .
35
35
class ClassTablePage extends StatefulWidget {
36
36
const ClassTablePage ({super .key});
37
37
38
38
@override
39
- State <ClassTablePage > createState () => _ClassTablePageState ();
39
+ State <StatefulWidget > createState () => _ClassTablePageState ();
40
40
}
41
41
42
42
class _ClassTablePageState extends State <ClassTablePage > {
43
+ /// A lock of the week choice row.
44
+ /// When locked, choiceWeek cannot be changed.
45
+ bool isTopRowLocked = false ;
46
+
47
+ /// Classtable pageView controller.
48
+ late PageController pageControl;
49
+
50
+ /// Week choice row controller.
51
+ late PageController rowControl;
52
+
43
53
late BoxDecoration decoration;
44
54
late ClassTableState classTableState;
45
55
@@ -56,13 +66,87 @@ class _ClassTablePageState extends State<ClassTablePage> {
56
66
)
57
67
: null ,
58
68
);
69
+
59
70
super .initState ();
60
71
}
61
72
62
73
@override
63
74
void didChangeDependencies () {
64
- super .didChangeDependencies ();
65
75
classTableState = ClassTableState .of (context)! ;
76
+ log ("Classtable state inited, ${classTableState .currentWeek }" );
77
+ pageControl = PageController (
78
+ initialPage: classTableState.controllers.chosenWeek,
79
+ keepPage: true ,
80
+ );
81
+
82
+ /// (weekButtonWidth + 2 * weekButtonHorizontalPadding)
83
+ /// is the width of the week choose button.
84
+ rowControl = PageController (
85
+ initialPage: classTableState.controllers.chosenWeek,
86
+ viewportFraction: (weekButtonWidth + 2 * weekButtonHorizontalPadding) /
87
+ MediaQuery .sizeOf (context).width,
88
+ keepPage: true ,
89
+ );
90
+
91
+ super .didChangeDependencies ();
92
+ }
93
+
94
+ /// Change the position in the topRow
95
+ void changeTopRow (int index) => rowControl.animateTo (
96
+ (weekButtonWidth + 2 * weekButtonHorizontalPadding) * index,
97
+ curve: Curves .easeInOut,
98
+ duration: const Duration (milliseconds: changePageTime),
99
+ );
100
+
101
+ /// A row shows a series of buttons about the classtable's index.
102
+ ///
103
+ /// This is at the top of the classtable. It contains a series of
104
+ /// buttons which shows the week index, as well as an overview in a 5x5 dot gridview.
105
+ ///
106
+ /// When user click on the button, the pageview will show the class table of the
107
+ /// week the button suggested.
108
+ Widget _topView () {
109
+ return SizedBox (
110
+ /// Related to the overview of the week.
111
+ height: MediaQuery .sizeOf (context).height >= 500
112
+ ? topRowHeightBig
113
+ : topRowHeightSmall,
114
+ child: Container (
115
+ padding: const EdgeInsets .only (
116
+ top: 2 ,
117
+ bottom: 4 ,
118
+ ),
119
+ child: PageView .builder (
120
+ controller: rowControl,
121
+ physics: const ClampingScrollPhysics (),
122
+ scrollDirection: Axis .horizontal,
123
+ itemCount: classTableState.semesterLength,
124
+ itemBuilder: (BuildContext context, int index) {
125
+ return WeekChoiceButton (
126
+ onTap: () {
127
+ isTopRowLocked = true ;
128
+
129
+ /// The following sequence is used when triggering changing page.
130
+ /// * topRowLocked
131
+ /// * change the chosen week
132
+ /// * trigger pageview controller [pageControl] change, as well as
133
+ /// * change the [WeekChoiceRow]
134
+ classTableState.controllers.chosenWeek = index;
135
+ pageControl.animateToPage (
136
+ index,
137
+ curve: Curves .easeInOutCubic,
138
+ duration: const Duration (milliseconds: changePageTime),
139
+ );
140
+ changeTopRow (index);
141
+
142
+ setState (() {});
143
+ },
144
+ index: index,
145
+ );
146
+ },
147
+ ),
148
+ ),
149
+ );
66
150
}
67
151
68
152
/// If no class, a special page appears.
@@ -109,25 +193,31 @@ class _ClassTablePageState extends State<ClassTablePage> {
109
193
? topRowHeightBig
110
194
: topRowHeightSmall,
111
195
),
112
- child: const WeekChoiceRow (),
196
+ child: _topView (),
113
197
),
114
198
Expanded (
115
199
child: DecoratedBox (
116
200
decoration: decoration,
117
- child: const ClassTablePageView (),
201
+ child: _classTablePage (),
118
202
),
119
203
),
120
204
],
121
205
)
122
206
: Container (
123
207
decoration: decoration,
208
+ // color: Colors.grey.shade200.withOpacity(0.75),
124
209
child: const Center (
125
210
child: Column (
126
211
mainAxisAlignment: MainAxisAlignment .center,
127
212
children: [
128
- Icon (Icons .error, size: 100 ),
129
- SizedBox (height: 30 ),
130
- Text ("本学期学期没有课程,不会吧?" ),
213
+ Icon (
214
+ Icons .error,
215
+ size: 100 ,
216
+ ),
217
+ SizedBox (
218
+ height: 30 ,
219
+ ),
220
+ Text ("这个学期没有课程,不会吧?" ),
131
221
Text ("如果你没选课,快去 xk.xidian.edu.cn!" ),
132
222
Text ("如果你要毕业了,祝你前程似锦。" ),
133
223
Text ("如果你已经毕业,快去关注 SuperBart 哔哩哔哩帐号!" ),
@@ -137,4 +227,31 @@ class _ClassTablePageState extends State<ClassTablePage> {
137
227
),
138
228
);
139
229
}
230
+
231
+ /// The [_classTablePage] is controlled by [pageControl] .
232
+ Widget _classTablePage () => PageView .builder (
233
+ scrollDirection: Axis .horizontal,
234
+ controller: pageControl,
235
+ onPageChanged: (value) {
236
+ /// When [pageControl.animateTo] triggered,
237
+ /// page view will try to refresh the [chosenWeek] everytime the page
238
+ /// view changed into a new page. Because animateTo will load every page
239
+ /// it passed.
240
+ ///
241
+ /// So that's the [isTopRowLocked] is used for. When week choice row is
242
+ /// locked, it will not refresh the [chosenWeek] . And when [chosenWeek]
243
+ /// is equal to the current page, unlock the [isTopRowLocked] .
244
+ if (! isTopRowLocked) {
245
+ setState (() {
246
+ changeTopRow (value);
247
+ classTableState.controllers.chosenWeek = value;
248
+ });
249
+ }
250
+ if (classTableState.controllers.chosenWeek == value) {
251
+ isTopRowLocked = false ;
252
+ }
253
+ },
254
+ itemCount: classTableState.semesterLength,
255
+ itemBuilder: (context, index) => ClassTableView (index: index),
256
+ );
140
257
}
0 commit comments