首页 > 解决方案 > setState() 在构造函数中调用:_ModalIngredientsState#60ddf(生命周期状态:已创建,无小部件,未安装)

问题描述

我有一个对话框,我需要用三个按钮打开它,当对话框打开时,我有两个按钮可以关闭它,我需要返回主屏幕,这是对话框覆盖的屏幕


    class ModalIngredients extends StatefulWidget {
      const ModalIngredients({Key key}) : super(key: key);
      showModalAddIngredients(BuildContext context) =>
          createState().showModalAddIngredients(context);
      @override
      _ModalIngredientsState createState() => _ModalIngredientsState();
    }
    
    class _ModalIngredientsState extends State<ModalIngredients> {
      TextEditingController _textFieldController = TextEditingController();
    
      showModalAddIngredients(context) {
        showDialog(
            context: context,
            builder: (context) {
              return AlertDialog(
                title: Text('Adicionar Ingrediente'),
                content: TextField(
                  onChanged: (value) {
                    setState(() {
                      valueText = value;
                    });
                  },
                  controller: _textFieldController,
                  decoration: InputDecoration(hintText: "Ex: Trigo"),
                ),
                actions: <Widget>[
                  FlatButton(
                    color: Colors.red,
                    textColor: Colors.white,
                    child: Text('Cancelar'),
                    onPressed: () {
                      setState(() {
                        Navigator.pop(context);
                      });
                    },
                  ),
                  FlatButton(
                    color: Colors.green,
                    textColor: Colors.white,
                    child: Text('Salvar'),
                    onPressed: () {
                      setState(() {
                        codeDialog = valueText;
                        Navigator.pop(context);
                      });
                    },
                  ),
                ],
              );
            });
      }
    
      String codeDialog;
      String valueText;
    
      @override
      Widget build(BuildContext context) {
        return Container();
      }
    }

════════ 手势捕捉到异常═════════════════════════════════════════════════════════ ═════ 处理手势时抛出以下断言: setState() 在构造函数中调用:_ModalIngredientsState#adab3(生命周期状态:已创建,无小部件,未安装) 2

当您对尚未插入到小部件树的小部件的 State 对象调用 setState() 时,就会发生这种情况。没有必要在构造函数中调用 setState(),因为在最初创建状态时已经假定状态是脏的。

标签: flutter

解决方案


您无法运行您的showModalAddIngredients()方法,因为showDialog会导致当前小部件的重建(为了显示对话框小部件)。在当前正在进行构建,您不得要求进行重建。

在托管小部件完成其初始构建/渲染后,您可以使用它WidgetsBinding.instance.addPostFrameCallback()来执行一些操作。

  @override
  Widget build(BuildContext context) {
    /// This allows you to do something after the initial build is complete
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) => showModalAddIngredients(context));

完整示例

import 'package:flutter/material.dart';

class ModalIngredients extends StatefulWidget {
  //const ModalIngredients({Key key}) : super(key: key);
  /// Don't do this.  Generally, nothing goes into the StatefulWidget except
  /// final arguments to be used in the State<T> object
  /*showModalAddIngredients(BuildContext context) =>
      createState().showModalAddIngredients(context);*/
  @override
  _ModalIngredientsState createState() => _ModalIngredientsState();
}

class _ModalIngredientsState extends State<ModalIngredients> {
  TextEditingController _textFieldController = TextEditingController();

  showModalAddIngredients(context) {
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('Adicionar Ingrediente'),
            content: TextField(
              onChanged: (value) {
                setState(() {
                  valueText = value;
                });
              },
              controller: _textFieldController,
              decoration: InputDecoration(hintText: "Ex: Trigo"),
            ),
            actions: <Widget>[
              FlatButton(
                color: Colors.red,
                textColor: Colors.white,
                child: Text('Cancelar'),
                onPressed: () {
                  setState(() {
                    Navigator.pop(context);
                  });
                },
              ),
              FlatButton(
                color: Colors.green,
                textColor: Colors.white,
                child: Text('Salvar'),
                onPressed: () {
                  setState(() {
                    codeDialog = valueText;
                    Navigator.pop(context);
                  });
                },
              ),
            ],
          );
        });
  }

  String codeDialog;
  String valueText;

  @override
  Widget build(BuildContext context) {
    /// This allows you to do something after the initial build is complete
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) => showModalAddIngredients(context));

    return Scaffold(
      body: Container(),
    );
  }
}

推荐阅读