fix red screen of death caused by overlay not disposing

This commit is contained in:
Brighton van den End 2022-11-21 14:53:07 +01:00
parent 66e0090597
commit a3fcfabb01
4 changed files with 134 additions and 104 deletions

View file

@ -20,12 +20,7 @@ class MyApp extends StatelessWidget {
theme: ThemeData( theme: ThemeData(
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
), ),
home: Scaffold( home: const DatePickerDemo(),
appBar: AppBar(
title: const Text('Demo'),
),
body: const DatePickerDemo(),
),
); );
} }
} }
@ -58,86 +53,99 @@ class DatePickerDemo extends StatelessWidget {
barColor: Colors.black, barColor: Colors.black,
barOpacity: 1, barOpacity: 1,
), ),
paginationSize: 50,
); );
return Stack( return Scaffold(
children: [ appBar: AppBar(
Center( automaticallyImplyLeading: true,
child: Column( title: const Text('Demo'),
mainAxisAlignment: MainAxisAlignment.spaceEvenly, ),
children: [ body: Stack(
OverlayDateTimePicker( children: [
theme: dateTimePickerTheme, Center(
alignment: Alignment.bottomCenter, child: Column(
child: const Text("Select Day"), mainAxisAlignment: MainAxisAlignment.spaceEvenly,
onTapDay: (date) {}, children: [
), OverlayDateTimePicker(
OverlayDateTimePicker( theme: dateTimePickerTheme,
theme: dateTimePickerTheme, alignment: Alignment.bottomCenter,
alignment: Alignment.center,
buttonBuilder: (key, onPressed) => TextButton(
key: key,
onPressed: onPressed,
child: const Text("Select Day"), child: const Text("Select Day"),
onTapDay: (date) {},
), ),
dateTimeConstraint: DateTimeConstraint( OverlayDateTimePicker(
min: DateConstraint(date: DateTime.now()), theme: dateTimePickerTheme,
), alignment: Alignment.center,
), buttonBuilder: (key, onPressed) => TextButton(
OverlayDateTimePicker( key: key,
theme: dateTimePickerTheme, onPressed: onPressed,
alignment: Alignment.topCenter, child: const Text("Select Day"),
buttonBuilder: (key, onPressed) => IconButton( ),
key: key, dateTimeConstraint: DateTimeConstraint(
onPressed: onPressed, min: DateConstraint(date: DateTime.now()),
icon: const Icon(
Icons.schedule,
), ),
), ),
dateTimeConstraint: DateTimeConstraint( OverlayDateTimePicker(
min: DateConstraint(date: DateTime.now()), theme: dateTimePickerTheme,
max: DateConstraint( alignment: Alignment.topCenter,
date: DateTime( buttonBuilder: (key, onPressed) => IconButton(
DateTime.now().year, key: key,
DateTime.now().month + 4, onPressed: onPressed,
DateTime.now().day, icon: const Icon(
Icons.schedule,
), ),
), ),
dateTimeConstraint: DateTimeConstraint(
min: DateConstraint(date: DateTime.now()),
max: DateConstraint(
date: DateTime(
DateTime.now().year,
DateTime.now().month + 4,
DateTime.now().day,
),
),
),
onNextPageButtonBuilder: (onPressed) {
return IconButton(
onPressed: onPressed, icon: const Icon(Icons.add));
},
onPreviousPageButtonBuilder: (onPressed) {
return IconButton(
onPressed: onPressed, icon: const Icon(Icons.minimize));
},
)
],
),
),
DragDownDateTimePicker(
dateTimePickerTheme: const DateTimePickerTheme(
backgroundColor: Colors.white,
markedIndicatorColor: Colors.red,
baseTheme: DateBoxBaseTheme(
Colors.white,
TextStyle(color: Colors.black),
),
selectedTheme: DateBoxSelectedTheme(
Color(0x4BF44336),
TextStyle(
color: Colors.red,
), ),
onNextPageButtonChild: const Icon(Icons.add), ),
onPreviousPageButtonChild: const Icon(Icons.minimize), highlightTheme: DateBoxHighlightTheme(
) Colors.red,
], TextStyle(
), color: Colors.white,
), ),
DragDownDateTimePicker( ),
dateTimePickerTheme: const DateTimePickerTheme( barTheme: DateTimePickerBarTheme(
backgroundColor: Colors.white, barColor: Colors.black,
markedIndicatorColor: Colors.red, barOpacity: 1,
baseTheme: DateBoxBaseTheme(
Colors.white,
TextStyle(color: Colors.black),
),
selectedTheme: DateBoxSelectedTheme(
Color(0x4BF44336),
TextStyle(
color: Colors.red,
), ),
), ),
highlightTheme: DateBoxHighlightTheme( markedDates: [DateTime(2022, 9, 6)],
Colors.red, )
TextStyle( ],
color: Colors.white, ),
),
),
barTheme: DateTimePickerBarTheme(
barColor: Colors.black,
barOpacity: 1,
),
),
markedDates: [DateTime(2022, 9, 6)],
)
],
); );
} }
} }

View file

@ -7,8 +7,9 @@ import 'package:flutter_date_time_picker/flutter_date_time_picker.dart';
class DateTimePickerTheme { class DateTimePickerTheme {
/// The [DateTimePickerTheme] to style [DragDownDateTimePicker] in. Define a custom shape for the dates and specifically style /// The [DateTimePickerTheme] to style [DragDownDateTimePicker] in. Define a custom shape for the dates and specifically style
/// a basic, hightlighted, selected and disabled date. /// a basic, highlighted, selected and disabled date.
const DateTimePickerTheme({ const DateTimePickerTheme({
this.paginationSize = 25,
this.weekDateBoxSize = 35, this.weekDateBoxSize = 35,
this.monthDateBoxSize = 45, this.monthDateBoxSize = 45,
this.markedIndicatorColor, this.markedIndicatorColor,
@ -75,4 +76,7 @@ class DateTimePickerTheme {
/// The position where the week view changes to month view and the other way around. Enter a value between 0 and 1 that's between the weekViewSize and the monthViewSize. /// The position where the week view changes to month view and the other way around. Enter a value between 0 and 1 that's between the weekViewSize and the monthViewSize.
final double weekMonthTriggerSize; final double weekMonthTriggerSize;
/// The size of the buttons for navigation the different pages
final double paginationSize;
} }

View file

@ -29,8 +29,8 @@ class OverlayDateTimePicker extends StatefulWidget {
this.closeOnSelectDate = true, this.closeOnSelectDate = true,
this.showWeekDays = true, this.showWeekDays = true,
this.dateTimeConstraint = const DateTimeConstraint(), this.dateTimeConstraint = const DateTimeConstraint(),
this.onNextPageButtonChild, this.onNextPageButtonBuilder,
this.onPreviousPageButtonChild, this.onPreviousPageButtonBuilder,
}) : assert(child != null || buttonBuilder != null); }) : assert(child != null || buttonBuilder != null);
/// The child contained by the DatePicker. /// The child contained by the DatePicker.
@ -84,11 +84,12 @@ class OverlayDateTimePicker extends StatefulWidget {
/// a [DateTimeConstraint] that dictates the constraints of the dates that can be picked. /// a [DateTimeConstraint] that dictates the constraints of the dates that can be picked.
final DateTimeConstraint dateTimeConstraint; final DateTimeConstraint dateTimeConstraint;
/// a [Widget] that determents the icon of the button for going to the next page /// a [Function] that determents the icon of the button for going to the next page
final Widget? onNextPageButtonChild; final Widget Function(void Function()? onPressed)? onNextPageButtonBuilder;
/// a [Widget] that determents the icon of the button for going to the previous page /// a [Function] that determents the icon of the button for going to the previous page
final Widget? onPreviousPageButtonChild; final Widget Function(void Function()? onPressed)?
onPreviousPageButtonBuilder;
@override @override
State<OverlayDateTimePicker> createState() => _OverlayDateTimePickerState(); State<OverlayDateTimePicker> createState() => _OverlayDateTimePickerState();
@ -144,14 +145,15 @@ class _OverlayDateTimePickerState extends State<OverlayDateTimePicker> {
@override @override
void dispose() { void dispose() {
if (_overlay.mounted) _overlay.remove();
_overlay.dispose(); _overlay.dispose();
_overlayState?.dispose(); _overlayState = null;
_dateTimePickerController.dispose(); _dateTimePickerController.dispose();
super.dispose(); super.dispose();
} }
void _toggleOverlay() { void _toggleOverlay() {
if (mounted) { if (mounted && (_overlayState?.mounted ?? false)) {
setState(() { setState(() {
if (!_isShown) { if (!_isShown) {
_overlayState?.insert(_overlay); _overlayState?.insert(_overlay);
@ -232,8 +234,8 @@ class _OverlayDateTimePickerState extends State<OverlayDateTimePicker> {
onNextDate: nextDate, onNextDate: nextDate,
onPreviousDate: previousDate, onPreviousDate: previousDate,
dateTimeConstraint: widget.dateTimeConstraint, dateTimeConstraint: widget.dateTimeConstraint,
onNextPageButtonChild: widget.onNextPageButtonChild, onNextPageButtonChild: widget.onNextPageButtonBuilder,
onPreviousPageButtonChild: widget.onPreviousPageButtonChild, onPreviousPageButtonChild: widget.onPreviousPageButtonBuilder,
), ),
), ),
), ),

View file

@ -32,8 +32,8 @@ class OverlayDateTimeContent extends StatefulWidget {
final bool showWeekDays; final bool showWeekDays;
final DateTimeConstraint dateTimeConstraint; final DateTimeConstraint dateTimeConstraint;
final Widget? onNextPageButtonChild; final Widget Function(void Function()? onPressed)? onNextPageButtonChild;
final Widget? onPreviousPageButtonChild; final Widget Function(void Function()? onPressed)? onPreviousPageButtonChild;
final void Function() onNextDate; final void Function() onNextDate;
final void Function() onPreviousDate; final void Function() onPreviousDate;
@ -77,28 +77,42 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
IconButton( (widget.onPreviousPageButtonChild != null)
onPressed: (widget.dateTimeConstraint.inMonthRange(previousDate)) ? widget.onPreviousPageButtonChild!(
? _goToPreviousPage (widget.dateTimeConstraint.inMonthRange(previousDate))
: null, ? _goToPreviousPage
icon: widget.onPreviousPageButtonChild ?? : null,
const Icon(Icons.arrow_circle_left_outlined), )
color: widget.theme.barTheme.barColor, : IconButton(
), onPressed:
(widget.dateTimeConstraint.inMonthRange(previousDate))
? _goToPreviousPage
: null,
icon: const Icon(Icons.arrow_circle_left_outlined),
color: widget.theme.barTheme.barColor,
iconSize: widget.theme.paginationSize,
),
Text( Text(
DateFormat.yMMMM().format( DateFormat.yMMMM().format(
widget.controller.browsingDate, widget.controller.browsingDate,
), ),
style: widget.theme.baseTheme.textStyle, style: widget.theme.baseTheme.textStyle,
), ),
IconButton( (widget.onNextPageButtonChild != null)
onPressed: (widget.dateTimeConstraint.inMonthRange(nextDate)) ? widget.onNextPageButtonChild!(
? _goToNextPage (widget.dateTimeConstraint.inMonthRange(nextDate))
: null, ? _goToNextPage
icon: widget.onNextPageButtonChild ?? : null,
const Icon(Icons.arrow_circle_right_outlined), )
color: widget.theme.barTheme.barColor, : IconButton(
), onPressed:
(widget.dateTimeConstraint.inMonthRange(nextDate))
? _goToNextPage
: null,
icon: const Icon(Icons.arrow_circle_right_outlined),
color: widget.theme.barTheme.barColor,
iconSize: widget.theme.paginationSize,
),
], ],
), ),
Container( Container(
@ -158,6 +172,7 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
} }
void _goToNextPage() async { void _goToNextPage() async {
if (!mounted) return;
setState(() { setState(() {
usesButtons = true; usesButtons = true;
}); });
@ -169,6 +184,7 @@ class _OverlayDateTimeContentState extends State<OverlayDateTimeContent> {
} }
void _goToPreviousPage() async { void _goToPreviousPage() async {
if (!mounted) return;
setState(() { setState(() {
usesButtons = true; usesButtons = true;
}); });