@@ -10,6 +10,7 @@ import 'package:pdg_app/router/router.gr.dart';
10
10
import 'package:pdg_app/widgets/cards/arrow_pic_card.dart' ;
11
11
import 'package:pdg_app/widgets/loading_overlay.dart' ;
12
12
import 'package:provider/provider.dart' ;
13
+ import 'package:sticky_headers/sticky_headers.dart' ;
13
14
import 'package:table_calendar/table_calendar.dart' ;
14
15
import '../model/user.dart' ;
15
16
import '../api/firebase_file.dart' ;
@@ -146,12 +147,16 @@ class _DiaryState extends State<Diary> {
146
147
DateTime _selectedDay = DateTime .now ();
147
148
DateTime _focusedDay = DateTime .now ();
148
149
CalendarFormat _calendarFormat = CalendarFormat .week;
150
+ final _scrollController = ScrollController ();
149
151
150
152
@override
151
153
void initState () {
152
154
super .initState ();
153
155
154
156
_selectedDay = _focusedDay;
157
+ _scrollController.addListener (() {
158
+ if (_scrollController.position.pixels < 0 ) _scrollController.jumpTo (0 );
159
+ });
155
160
}
156
161
157
162
@override
@@ -171,7 +176,9 @@ class _DiaryState extends State<Diary> {
171
176
final DateFormat hourFormatter = DateFormat ('HH:mm' );
172
177
173
178
return Stack (children: [
174
- Column (
179
+ ListView (
180
+ controller: _scrollController,
181
+ physics: const BouncingScrollPhysics (),
175
182
children: [
176
183
DiaryTopBar (
177
184
background: background,
@@ -180,47 +187,51 @@ class _DiaryState extends State<Diary> {
180
187
clientPicturePath: widget.clientPicturePath,
181
188
defaultUserPic: widget._defaultUserPic,
182
189
),
183
- TableCalendar (
184
- firstDay: DateTime .utc (2020 , 1 , 1 ),
185
- lastDay: DateTime .utc (2050 , 12 , 31 ),
186
- focusedDay: _focusedDay,
187
- selectedDayPredicate: (day) {
188
- return isSameDay (_selectedDay, day);
189
- },
190
- onDaySelected: (selectedDay, focusedDay) {
191
- setState (() {
192
- _selectedDay = selectedDay;
193
- _focusedDay = focusedDay; // update `_focusedDay` here as well
194
- });
195
- if (widget._onDaySelected != null ) {
196
- widget._onDaySelected !(selectedDay);
197
- }
198
- },
199
- calendarFormat: _calendarFormat,
200
- onFormatChanged: (format) {
201
- setState (() {
202
- _calendarFormat = format;
203
- });
204
- },
205
- onPageChanged: (focusedDay) {
206
- _focusedDay = focusedDay;
207
- },
208
- eventLoader: context.read <MealProvider >().getMealsByDay,
209
- startingDayOfWeek: StartingDayOfWeek .monday,
210
- calendarStyle: CalendarStyle (
211
- todayDecoration: BoxDecoration (
212
- color: Theme .of (context).colorScheme.secondary,
213
- shape: BoxShape .circle),
214
- todayTextStyle:
215
- TextStyle (color: Theme .of (context).colorScheme.onSurface),
216
- selectedDecoration: BoxDecoration (
217
- color: Theme .of (context).colorScheme.primary,
218
- shape: BoxShape .circle),
190
+ StickyHeader (
191
+ header: Container (
192
+ color: Colors .white,
193
+ child: TableCalendar (
194
+ firstDay: DateTime .utc (2020 , 1 , 1 ),
195
+ lastDay: DateTime .utc (2050 , 12 , 31 ),
196
+ focusedDay: _focusedDay,
197
+ selectedDayPredicate: (day) {
198
+ return isSameDay (_selectedDay, day);
199
+ },
200
+ onDaySelected: (selectedDay, focusedDay) {
201
+ setState (() {
202
+ _selectedDay = selectedDay;
203
+ _focusedDay =
204
+ focusedDay; // update `_focusedDay` here as well
205
+ });
206
+ if (widget._onDaySelected != null ) {
207
+ widget._onDaySelected !(selectedDay);
208
+ }
209
+ },
210
+ calendarFormat: _calendarFormat,
211
+ onFormatChanged: (format) {
212
+ setState (() {
213
+ _calendarFormat = format;
214
+ });
215
+ },
216
+ onPageChanged: (focusedDay) {
217
+ _focusedDay = focusedDay;
218
+ },
219
+ eventLoader: context.read <MealProvider >().getMealsByDay,
220
+ startingDayOfWeek: StartingDayOfWeek .monday,
221
+ calendarStyle: CalendarStyle (
222
+ todayDecoration: BoxDecoration (
223
+ color: Theme .of (context).colorScheme.secondary,
224
+ shape: BoxShape .circle),
225
+ todayTextStyle:
226
+ TextStyle (color: Theme .of (context).colorScheme.onSurface),
227
+ selectedDecoration: BoxDecoration (
228
+ color: Theme .of (context).colorScheme.primary,
229
+ shape: BoxShape .circle),
230
+ ),
231
+ ),
219
232
),
220
- ),
221
- const SizedBox (height: 13 ),
222
- Expanded (
223
- child: _CalendarBody (
233
+ content: _CalendarBody (
234
+ topBarHeight: height,
224
235
defaultMealPic: widget._defaultMealPic,
225
236
hourFormatter: hourFormatter,
226
237
meals: context.read <MealProvider >().getMealsByDay (_selectedDay),
@@ -242,24 +253,23 @@ class _CalendarBody extends StatelessWidget {
242
253
final List <Meal > meals;
243
254
final void Function (Meal )? onMealBlocPressed;
244
255
final String defaultMealPic;
256
+ final double topBarHeight;
245
257
246
258
const _CalendarBody ({
247
259
required this .meals,
248
260
Key ? key,
249
261
required this .hourFormatter,
250
262
required this .defaultMealPic,
251
263
this .onMealBlocPressed,
264
+ required this .topBarHeight,
252
265
}) : super (key: key);
253
266
254
267
final DateFormat hourFormatter;
255
268
256
- @override
257
- Widget build (BuildContext context) {
258
- return ListView .builder (
259
- itemCount: meals.length,
260
- physics: const BouncingScrollPhysics (),
261
- itemBuilder: (context, index) {
262
- return GestureDetector (
269
+ List <Widget > buildList () {
270
+ return < Widget > [
271
+ for (int index = 0 ; index < meals.length; index++ )
272
+ GestureDetector (
263
273
onTap: onMealBlocPressed != null
264
274
? (() => onMealBlocPressed !(meals[index]))
265
275
: () {},
@@ -281,8 +291,17 @@ class _CalendarBody extends StatelessWidget {
281
291
),
282
292
),
283
293
),
284
- );
285
- },
294
+ )
295
+ ];
296
+ }
297
+
298
+ @override
299
+ Widget build (BuildContext context) {
300
+ return Column (
301
+ children: [
302
+ ...buildList (),
303
+ SizedBox (height: topBarHeight - 10 ),
304
+ ],
286
305
);
287
306
}
288
307
}
0 commit comments