Skip to content

Commit 38c4c35

Browse files
authored
Merge pull request #210 from les-crepes/209-meal-stickyheader
sticky header
2 parents f9231d1 + 4f86d56 commit 38c4c35

File tree

3 files changed

+77
-50
lines changed

3 files changed

+77
-50
lines changed

lib/screens/diary.dart

+69-50
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:pdg_app/router/router.gr.dart';
1010
import 'package:pdg_app/widgets/cards/arrow_pic_card.dart';
1111
import 'package:pdg_app/widgets/loading_overlay.dart';
1212
import 'package:provider/provider.dart';
13+
import 'package:sticky_headers/sticky_headers.dart';
1314
import 'package:table_calendar/table_calendar.dart';
1415
import '../model/user.dart';
1516
import '../api/firebase_file.dart';
@@ -146,12 +147,16 @@ class _DiaryState extends State<Diary> {
146147
DateTime _selectedDay = DateTime.now();
147148
DateTime _focusedDay = DateTime.now();
148149
CalendarFormat _calendarFormat = CalendarFormat.week;
150+
final _scrollController = ScrollController();
149151

150152
@override
151153
void initState() {
152154
super.initState();
153155

154156
_selectedDay = _focusedDay;
157+
_scrollController.addListener(() {
158+
if (_scrollController.position.pixels < 0) _scrollController.jumpTo(0);
159+
});
155160
}
156161

157162
@override
@@ -171,7 +176,9 @@ class _DiaryState extends State<Diary> {
171176
final DateFormat hourFormatter = DateFormat('HH:mm');
172177

173178
return Stack(children: [
174-
Column(
179+
ListView(
180+
controller: _scrollController,
181+
physics: const BouncingScrollPhysics(),
175182
children: [
176183
DiaryTopBar(
177184
background: background,
@@ -180,47 +187,51 @@ class _DiaryState extends State<Diary> {
180187
clientPicturePath: widget.clientPicturePath,
181188
defaultUserPic: widget._defaultUserPic,
182189
),
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+
),
219232
),
220-
),
221-
const SizedBox(height: 13),
222-
Expanded(
223-
child: _CalendarBody(
233+
content: _CalendarBody(
234+
topBarHeight: height,
224235
defaultMealPic: widget._defaultMealPic,
225236
hourFormatter: hourFormatter,
226237
meals: context.read<MealProvider>().getMealsByDay(_selectedDay),
@@ -242,24 +253,23 @@ class _CalendarBody extends StatelessWidget {
242253
final List<Meal> meals;
243254
final void Function(Meal)? onMealBlocPressed;
244255
final String defaultMealPic;
256+
final double topBarHeight;
245257

246258
const _CalendarBody({
247259
required this.meals,
248260
Key? key,
249261
required this.hourFormatter,
250262
required this.defaultMealPic,
251263
this.onMealBlocPressed,
264+
required this.topBarHeight,
252265
}) : super(key: key);
253266

254267
final DateFormat hourFormatter;
255268

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(
263273
onTap: onMealBlocPressed != null
264274
? (() => onMealBlocPressed!(meals[index]))
265275
: () {},
@@ -281,8 +291,17 @@ class _CalendarBody extends StatelessWidget {
281291
),
282292
),
283293
),
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+
],
286305
);
287306
}
288307
}

pubspec.lock

+7
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,13 @@ packages:
868868
url: "https://pub.dartlang.org"
869869
source: hosted
870870
version: "1.10.0"
871+
sticky_headers:
872+
dependency: "direct main"
873+
description:
874+
name: sticky_headers
875+
url: "https://pub.dartlang.org"
876+
source: hosted
877+
version: "0.3.0+2"
871878
stream_channel:
872879
dependency: transitive
873880
description:

pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ dependencies:
6161
tuple: ^2.0.0
6262
flutter_svg: ^1.1.4
6363
flutter_dotenv: ^5.0.2
64+
sticky_headers: ^0.3.0+2
6465

6566
dev_dependencies:
6667
flutter_test:

0 commit comments

Comments
 (0)