I am using the same stateful widget in 2 different views. It's using a list of TextEditingController
that I send as a delegate through
this 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
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.