当小部件从 window 中删除时不会调用 Dispose - Flutter
Dispose isn't called when the widgets removed from the window - Flutter
我在 2 个不同的视图中使用同一个有状态小部件。它使用我作为代表通过
发送的 TextEditingController
列表
这是 TextController 列表:
var textfieldControllersEx = [
TextEditingController(),
TextEditingController(),
TextEditingController(),
TextEditingController(),
];
提取的小部件在 2 个不同的视图中使用了两次:
ExpiryDateTextField(
controllers: textfieldControllersEx,
onChangeF: (String value, int i) {
setState(() {
_addValuesToAr(value, i);
});
},
),
在每个视图上,我都在 ExpiryDateTextField
函数中调用了一个 dispose 和一个 dispose 以及打印以查看它是否被处理:
它甚至没有在任何一个页面上调用 dispose
@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();
}
这是函数:
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]
),
),
],
);
}
}
这是给出的错误:
I/flutter (24293): Another exception was thrown:
dependOnInheritedWidgetOfExactType<_ModalScopeStatus>() or
dependOnInheritedElement() was called before _ViewState.initState()
completed.
我看到了这个例子,但它没有用,因为如果一个值被改变,它会立即处理 TextControllers :
@override
void didChangeDependencies() {
textfieldControllersEx[0].dispose();
textfieldControllersEx[1].dispose();
textfieldControllersEx[2].dispose();
textfieldControllersEx[3].dispose();
// TODO: implement didChangeDependencies
super.didChangeDependencies();
}
这就是我的导航方式:
Navigator.of(context).pushNamed("/PlaidPage");
不胜感激
未调用 dispose()
的原因是屏幕仍在导航堆栈中。您可以使用 Navigator.pop()
或 Navigator.of(context).pushNamedAndRemoveUntil()
删除当前屏幕 - 删除到指定页面并导航到下一页。
我在 2 个不同的视图中使用同一个有状态小部件。它使用我作为代表通过
发送的TextEditingController
列表
这是 TextController 列表:
var textfieldControllersEx = [
TextEditingController(),
TextEditingController(),
TextEditingController(),
TextEditingController(),
];
提取的小部件在 2 个不同的视图中使用了两次:
ExpiryDateTextField(
controllers: textfieldControllersEx,
onChangeF: (String value, int i) {
setState(() {
_addValuesToAr(value, i);
});
},
),
在每个视图上,我都在 ExpiryDateTextField
函数中调用了一个 dispose 和一个 dispose 以及打印以查看它是否被处理:
它甚至没有在任何一个页面上调用 dispose
@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();
}
这是函数:
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]
),
),
],
);
}
}
这是给出的错误:
I/flutter (24293): Another exception was thrown: dependOnInheritedWidgetOfExactType<_ModalScopeStatus>() or dependOnInheritedElement() was called before _ViewState.initState() completed.
我看到了这个例子,但它没有用,因为如果一个值被改变,它会立即处理 TextControllers :
@override
void didChangeDependencies() {
textfieldControllersEx[0].dispose();
textfieldControllersEx[1].dispose();
textfieldControllersEx[2].dispose();
textfieldControllersEx[3].dispose();
// TODO: implement didChangeDependencies
super.didChangeDependencies();
}
这就是我的导航方式:
Navigator.of(context).pushNamed("/PlaidPage");
不胜感激
未调用 dispose()
的原因是屏幕仍在导航堆栈中。您可以使用 Navigator.pop()
或 Navigator.of(context).pushNamedAndRemoveUntil()
删除当前屏幕 - 删除到指定页面并导航到下一页。