@@ -88,12 +88,17 @@ class GenericDropdown extends StatefulWidget {
88
88
/// [DropdownDirection] . Defaults to [Offset.zero] .
89
89
final Offset offset;
90
90
91
+ /// Whether the content should close if any click/tap happens
92
+ /// outside the content container. Defaults to `true` .
93
+ final bool closeOnOutsideTap;
94
+
91
95
const GenericDropdown (
92
96
{super .key,
93
97
required this .contentBuilder,
94
98
this .anchor = DropdownAnchor .bottomLeft,
95
99
this .direction = DropdownDirection .downRight,
96
100
required this .toggleBuilder,
101
+ this .closeOnOutsideTap = true ,
97
102
this .offset = Offset .zero});
98
103
99
104
@override
@@ -149,70 +154,70 @@ class _GenericDropdownState extends State<GenericDropdown> {
149
154
150
155
// Anchor TOP LEFT
151
156
if (widget.anchor == DropdownAnchor .topLeft && widget.direction == DropdownDirection .upLeft) {
152
- bottom = screenSize.height - togglePosition.dy + ( widget.offset? .dy ?? 0 ) ;
153
- right = screenSize.width - togglePosition.dx + ( widget.offset? .dx ?? 0 ) ;
157
+ bottom = screenSize.height - togglePosition.dy + widget.offset.dy;
158
+ right = screenSize.width - togglePosition.dx + widget.offset.dx;
154
159
} else if (widget.anchor == DropdownAnchor .topLeft && widget.direction == DropdownDirection .upRight) {
155
- bottom = screenSize.height - togglePosition.dy + ( widget.offset? .dy ?? 0 ) ;
156
- left = togglePosition.dx + ( widget.offset? .dx ?? 0 ) ;
160
+ bottom = screenSize.height - togglePosition.dy + widget.offset.dy;
161
+ left = togglePosition.dx + widget.offset.dx;
157
162
} else if (widget.anchor == DropdownAnchor .topLeft && widget.direction == DropdownDirection .downLeft) {
158
- top = togglePosition.dy + ( widget.offset? .dy ?? 0 ) ;
159
- right = screenSize.width - togglePosition.dx + ( widget.offset? .dx ?? 0 ) ;
163
+ top = togglePosition.dy + widget.offset.dy;
164
+ right = screenSize.width - togglePosition.dx + widget.offset.dx;
160
165
} else if (widget.anchor == DropdownAnchor .topLeft && widget.direction == DropdownDirection .downRight) {
161
- top = togglePosition.dy + ( widget.offset? .dy ?? 0 ) ;
162
- left = togglePosition.dx + ( widget.offset? .dx ?? 0 ) ;
166
+ top = togglePosition.dy + widget.offset.dy;
167
+ left = togglePosition.dx + widget.offset.dx;
163
168
}
164
169
165
170
// Anchor TOP RIGHT
166
171
if (widget.anchor == DropdownAnchor .topRight && widget.direction == DropdownDirection .upLeft) {
167
- bottom = screenSize.height - togglePosition.dy + ( widget.offset? .dy ?? 0 ) ;
168
- right = screenSize.width - togglePosition.dx + ( widget.offset? .dx ?? 0 ) - size.width;
172
+ bottom = screenSize.height - togglePosition.dy + widget.offset.dy;
173
+ right = screenSize.width - togglePosition.dx + widget.offset.dx - size.width;
169
174
} else if (widget.anchor == DropdownAnchor .topRight && widget.direction == DropdownDirection .upRight) {
170
- bottom = screenSize.height - togglePosition.dy + ( widget.offset? .dy ?? 0 ) ;
171
- left = togglePosition.dx + ( widget.offset? .dx ?? 0 ) + size.width;
175
+ bottom = screenSize.height - togglePosition.dy + widget.offset.dy;
176
+ left = togglePosition.dx + widget.offset.dx + size.width;
172
177
} else if (widget.anchor == DropdownAnchor .topRight && widget.direction == DropdownDirection .downLeft) {
173
- top = togglePosition.dy + ( widget.offset? .dy ?? 0 ) ;
174
- right = screenSize.width - togglePosition.dx + ( widget.offset? .dx ?? 0 ) - size.width;
178
+ top = togglePosition.dy + widget.offset.dy;
179
+ right = screenSize.width - togglePosition.dx + widget.offset.dx - size.width;
175
180
} else if (widget.anchor == DropdownAnchor .topRight && widget.direction == DropdownDirection .downRight) {
176
- top = togglePosition.dy + ( widget.offset? .dy ?? 0 ) ;
177
- left = togglePosition.dx + ( widget.offset? .dx ?? 0 ) + size.width;
181
+ top = togglePosition.dy + widget.offset.dy;
182
+ left = togglePosition.dx + widget.offset.dx + size.width;
178
183
}
179
184
180
185
// Anchor BOTTOM LEFT
181
186
if (widget.anchor == DropdownAnchor .bottomLeft && widget.direction == DropdownDirection .upLeft) {
182
- bottom = screenSize.height - togglePosition.dy + ( widget.offset? .dy ?? 0 ) - size.height;
183
- right = screenSize.width - togglePosition.dx + ( widget.offset? .dx ?? 0 ) ;
187
+ bottom = screenSize.height - togglePosition.dy + widget.offset.dy - size.height;
188
+ right = screenSize.width - togglePosition.dx + widget.offset.dx;
184
189
} else if (widget.anchor == DropdownAnchor .bottomLeft && widget.direction == DropdownDirection .upRight) {
185
- bottom = screenSize.height - togglePosition.dy + ( widget.offset? .dy ?? 0 ) - size.height;
186
- left = togglePosition.dx + ( widget.offset? .dx ?? 0 ) ;
190
+ bottom = screenSize.height - togglePosition.dy + widget.offset.dy - size.height;
191
+ left = togglePosition.dx + widget.offset.dx;
187
192
} else if (widget.anchor == DropdownAnchor .bottomLeft && widget.direction == DropdownDirection .downLeft) {
188
- top = togglePosition.dy + ( widget.offset? .dy ?? 0 ) + size.height;
189
- right = screenSize.width - togglePosition.dx + ( widget.offset? .dx ?? 0 ) ;
193
+ top = togglePosition.dy + widget.offset.dy + size.height;
194
+ right = screenSize.width - togglePosition.dx + widget.offset.dx;
190
195
} else if (widget.anchor == DropdownAnchor .bottomLeft && widget.direction == DropdownDirection .downRight) {
191
- top = togglePosition.dy + ( widget.offset? .dy ?? 0 ) + size.height;
192
- left = togglePosition.dx + ( widget.offset? .dx ?? 0 ) ;
196
+ top = togglePosition.dy + widget.offset.dy + size.height;
197
+ left = togglePosition.dx + widget.offset.dx;
193
198
}
194
199
195
200
// Anchor BOTTOM RIGHT
196
201
if (widget.anchor == DropdownAnchor .bottomRight && widget.direction == DropdownDirection .upLeft) {
197
- bottom = screenSize.height - togglePosition.dy + ( widget.offset? .dy ?? 0 ) - size.height;
198
- right = screenSize.width - togglePosition.dx + ( widget.offset? .dx ?? 0 ) - size.width;
202
+ bottom = screenSize.height - togglePosition.dy + widget.offset.dy - size.height;
203
+ right = screenSize.width - togglePosition.dx + widget.offset.dx - size.width;
199
204
} else if (widget.anchor == DropdownAnchor .bottomRight && widget.direction == DropdownDirection .upRight) {
200
- bottom = screenSize.height - togglePosition.dy + ( widget.offset? .dy ?? 0 ) - size.height;
201
- left = togglePosition.dx + ( widget.offset? .dx ?? 0 ) + size.width;
205
+ bottom = screenSize.height - togglePosition.dy + widget.offset.dy - size.height;
206
+ left = togglePosition.dx + widget.offset.dx + size.width;
202
207
} else if (widget.anchor == DropdownAnchor .bottomRight && widget.direction == DropdownDirection .downLeft) {
203
- top = togglePosition.dy + ( widget.offset? .dy ?? 0 ) + size.height;
204
- right = screenSize.width - togglePosition.dx + ( widget.offset? .dx ?? 0 ) - size.width;
208
+ top = togglePosition.dy + widget.offset.dy + size.height;
209
+ right = screenSize.width - togglePosition.dx + widget.offset.dx - size.width;
205
210
} else if (widget.anchor == DropdownAnchor .bottomRight && widget.direction == DropdownDirection .downRight) {
206
- top = togglePosition.dy + ( widget.offset? .dy ?? 0 ) + size.height;
207
- left = togglePosition.dx + ( widget.offset? .dx ?? 0 ) + size.width;
211
+ top = togglePosition.dy + widget.offset.dy + size.height;
212
+ left = togglePosition.dx + widget.offset.dx + size.width;
208
213
}
209
214
210
215
_overlayEntry = OverlayEntry (
211
216
maintainState: true ,
212
217
builder: (context) => Material (
213
218
color: Colors .transparent,
214
219
child: GestureDetector (
215
- onTap: _close,
220
+ onTap: () => widget.closeOnOutsideTap ? _close () : null ,
216
221
child: Container (
217
222
alignment: Alignment .topLeft,
218
223
color: Colors .transparent,
@@ -223,9 +228,17 @@ class _GenericDropdownState extends State<GenericDropdown> {
223
228
left: left,
224
229
bottom: bottom,
225
230
right: right,
226
- child: StatefulBuilder (
227
- builder: (context, setState) =>
228
- widget.contentBuilder.call (context, () => setState (() {}), _close)),
231
+ child: GestureDetector (
232
+ onTap: () {
233
+ // this gesture detector prevents
234
+ // the bubbling event that closes the
235
+ // content on a click inside the
236
+ // content.
237
+ },
238
+ child: StatefulBuilder (
239
+ builder: (context, setState) =>
240
+ widget.contentBuilder.call (context, () => setState (() {}), _close)),
241
+ ),
229
242
),
230
243
],
231
244
),
0 commit comments