Dispose isn't called when the widgets removed from the window - Flutter
The reason why dispose()
isn't called is because the Screen is still on the Navigation stack. You can remove the current screen by either using Navigator.pop()
or Navigator.of(context).pushNamedAndRemoveUntil()
- to remove till the specified page and navigate to the next page.
Dohan Smit
Updated on December 19, 2022Comments
-
Dohan Smit over 1 year
I am using the same stateful widget in 2 different views. It's using a list of
TextEditingController
that I send as a delegate throughthis is the list of TextControllers :
var textfieldControllersEx = [ TextEditingController(), TextEditingController(), TextEditingController(), TextEditingController(), ];
the Extracted widget is used twice in 2 different views:
ExpiryDateTextField( controllers: textfieldControllersEx, onChangeF: (String value, int i) { setState(() { _addValuesToAr(value, i); }); }, ),
on every view I call a dispose and a dispose in the
ExpiryDateTextField
Function as well with a print to see if it's being disposed:It doesn't even call the dispose on either pages
@override void dispose() { Print.yellow('DISPOSED'); textfieldControllersEx[0].dispose(); textfieldControllersEx[1].dispose(); textfieldControllersEx[2].dispose(); textfieldControllersEx[3].dispose(); textfieldControllersEx[0].text = null; textfieldControllersEx[1].text = null; textfieldControllersEx[2].text = null; textfieldControllersEx[3].text = null; // TODO: implement dispose super.dispose(); }
this is the function :
var focusNodes = [ FocusNode(), FocusNode(), FocusNode(), FocusNode(), ]; class ExpiryDateTextField extends StatefulWidget { final List<TextEditingController> controllers; final Function onChangeF; ExpiryDateTextField({this.controllers, this.onChangeF}); @override _ExpiryDateTextFieldState createState() => _ExpiryDateTextFieldState(); } class _ExpiryDateTextFieldState extends State<ExpiryDateTextField> { @override void dispose() { // TODO: implement dispose super.dispose(); } @override Widget build(BuildContext context) { bool onSwitchChanged(value, context, index) { // print(index++); if (index == 4) { //if it is on the last text box, do nothing } else { if (widget.controllers[index].text.length > 0) { index++; FocusScope.of(context).requestFocus(focusNodes[index]); widget.controllers[index].selection = TextSelection( baseOffset: 0, extentOffset: widget.controllers[index].text.length ); // FocusScope.of(context).focus } } return true; } return Row( children: <Widget>[ Expanded( flex: 1, child: SingleDigitTextField( onChangedF: (value) { widget.onChangeF(value, 0); print(this.toString(minLevel: DiagnosticLevel.debug)); onSwitchChanged(value, context, 0); }, fNode: focusNodes[0], cController: widget.controllers[0] ), ), Expanded( flex: 1, child: SingleDigitTextField( onChangedF: (value) { widget.onChangeF(value, 1); onSwitchChanged(value, context, 1); }, fNode: focusNodes[1], cController: widget.controllers[1] ), ), Expanded( flex: 1, child: Text("/", textAlign: TextAlign.center, style: Theme.of(context).textTheme.display2 ), ), Expanded( flex: 1, child: SingleDigitTextField( onChangedF: (value) { widget.onChangeF(value, 2); onSwitchChanged(value, context, 2); }, fNode: focusNodes[2], cController: widget.controllers[2] ), ), Expanded( flex: 1, child: SingleDigitTextField( onChangedF: (value) { widget.onChangeF(value, 3); onSwitchChanged(value, context, 3); }, fNode: focusNodes[3], cController: widget.controllers[3] ), ), ], ); } }
this is the error given :
I/flutter (24293): Another exception was thrown: dependOnInheritedWidgetOfExactType<_ModalScopeStatus>() or dependOnInheritedElement() was called before _ViewState.initState() completed.
I saw this example but it didn't work because if a value is changed it disposes of the TextControllers immediately :
@override void didChangeDependencies() { textfieldControllersEx[0].dispose(); textfieldControllersEx[1].dispose(); textfieldControllersEx[2].dispose(); textfieldControllersEx[3].dispose(); // TODO: implement didChangeDependencies super.didChangeDependencies(); }
this is how I Navigate :
Navigator.of(context).pushNamed("/PlaidPage");
Help would be kindly appreciated
-
Manuel about 4 yearsI'm not quite sure, but don't you need a
Navigator.of(context).pushNamedAndRemoveUntil("/PlaidPage");
Otherwise the view is still on "behind" on the push/pop stack and the widgets are not disposed -
Michel Feinstein about 4 yearsCould you simplify your question with a smaller example? Try creating a new project and just place there the minimum amount of code to reproduce the issue.
-
Dohan Smit about 4 yearsThanks, @Manuel... I just needed to insert a
Navigator.pop(context);
before I useNavigator.of(context).pushNamed"/PlaidPage");
-
morgwai almost 3 yearsthere's an ongoing discussion regarding this on github. Please voice your support if you think it should be fixed in flutter
-