/
stack_router_scaffold.dart
148 lines (129 loc) · 4.27 KB
/
stack_router_scaffold.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import 'package:flutter/material.dart';
import 'package:stack_router/stack_router_actions.dart';
import 'package:stack_router/stack_router_app_bar.dart';
import 'package:stack_router/stack_router_inherited_data.dart';
import 'package:stack_router/stack_router_scaffold_messenger.dart';
import 'package:stack_router/stack_router_snack_bar.dart';
import 'package:stack_router/stack_router_snack_bar_for_state.dart';
import 'package:stack_router/stack_router_snack_bar_queue.dart';
/// A scaffold for a [StackRoute] that provides the route with the ability to show app bars, snack bars and
/// perform [StackRouterActions] accessible by the injected inherited widget using [StackRouterActions.of(context)].
class StackRouterScaffold extends StatefulWidget {
/// The child widget to display within the scaffold.
final Widget child;
/// An app bar to display at the top of the scaffold.
final StackRouterAppBar? appBar;
/// The color of the scaffold body.
final Color? color;
/// The height of the scaffold.
final double? height;
/// The width of the scaffold.
final double? width;
/// Whether the child widget of the scaffold should extend to under the app bar.
final bool extendBodyBehindAppBar;
/// The aligment of the child widget in the scaffold.
final Alignment? alignment;
const StackRouterScaffold({
required this.child,
this.appBar,
this.color,
this.height,
this.width,
this.alignment,
this.extendBodyBehindAppBar = false,
key,
}) : super(key: key);
@override
_StackRouterScaffoldState createState() => _StackRouterScaffoldState();
}
class _StackRouterScaffoldState extends State<StackRouterScaffold> {
late StackRouterSnackBarQueue _snackBarQueue;
StackRouterSnackBarQueueChangeEvent? _latestSnackBarEvent;
bool _hasAddedMessenger = false;
late StackRouterScaffoldMessenger _messenger;
@override
initState() {
super.initState();
_messenger = StackRouterScaffoldMessenger(
showSnackBar: _showSnackBar,
clearSnackBars: _clearSnackBars,
hideSnackBar: _hideSnackBar,
);
_snackBarQueue = StackRouterSnackBarQueue(onChange: (event) {
if (mounted) {
setState(() {
_latestSnackBarEvent = event;
});
}
});
}
_showSnackBar(StackRouterSnackBar snackBar) {
_snackBarQueue.enqueue(snackBar);
}
_clearSnackBars() {
_snackBarQueue.clearAll();
}
_hideSnackBar() {
_snackBarQueue.dequeue();
}
@override
build(context) {
final stackRouterInheritedData = StackRouterInheritedData.of(context)!;
final currentRoute = stackRouterInheritedData.route;
final appBar = widget.appBar;
if (!_hasAddedMessenger) {
_hasAddedMessenger = true;
stackRouterInheritedData.addMessenger(
route: currentRoute!,
messenger: _messenger,
);
}
return StackRouterActions(
pushRoute: stackRouterInheritedData.pushRoute,
popRoute: stackRouterInheritedData.popRoute,
switchRoute: stackRouterInheritedData.switchRoute,
clearSnackBars: ({String? route}) {
final clearSnackBars = stackRouterInheritedData.clearSnackBars;
return clearSnackBars(route: route);
},
hideSnackBar: ({String? route}) {
final hideSnackBar = stackRouterInheritedData.hideSnackBar;
return hideSnackBar(route: route);
},
showSnackBar: ({
String? route,
required StackRouterSnackBar snackBar,
}) {
final showSnackBar = stackRouterInheritedData.showSnackBar;
return showSnackBar(
route: route,
snackBar: snackBar,
);
},
child: Container(
color: widget.color ?? Colors.white,
height: widget.height,
width: widget.width,
child: Stack(
children: [
Container(
padding: EdgeInsets.only(
top: widget.extendBodyBehindAppBar || appBar == null
? 0
: appBar.height,
),
child: Container(
alignment: widget.alignment,
child: widget.child,
),
),
if (appBar != null) appBar,
StackRouterSnackBarForState(
event: _latestSnackBarEvent,
),
],
),
),
);
}
}