当小部件从 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() 删除当前屏幕 - 删除到指定页面并导航到下一页。