查找停用的小部件的祖先是不安全的

时间:2019-02-10 14:36:24

标签: android flutter

我是Flutter的新手,正在尝试通过对话框接收数据。 单击textField时,出现image2错误...

Layout's Image Error's Image

show(BuildContext context){

    var dialog = Dialog(
      child: Container(
        margin: EdgeInsets.all(8.0),
        child: Form(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              TextFormField(
                decoration: InputDecoration(
                    labelText: "Insira o número de telefone",
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(2.0)))),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  FlatButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text("Cancelar")),
                  FlatButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text("Aceitar"))
                ],
              )
            ],
          ),
        ),
      ),
    );

    showDialog(context: context,builder: (context){
      return dialog;
    });
  }

这是我的代码。

I/flutter (31032): Looking up a deactivated widget's ancestor is unsafe.
I/flutter (31032): At this point the state of the widget's element tree is no longer stable. To safely refer to a
I/flutter (31032): widget's ancestor in its dispose() method, save a reference to the ancestor by calling
I/flutter (31032): inheritFromWidgetOfExactType() in the widget's didChangeDependencies() method.
I/flutter (31032): 

8 个答案:

答案 0 :(得分:6)

使用这个:

Navigator.of(context,rootNavigator: true).pop();

代替

Navigator.of(context).pop();

答案 1 :(得分:5)

当您从上下文中弹出并尝试在弹出的上下文中打开新内容时,可能会发生这种情况。

()async{
    Navigator.of(context).pop();
    _alertPopUp(); // shows a dialog
    // might do some work after
}

如果在当前上下文中创建了警报对话框,则会抛出错误,因为上下文不再存在

答案 2 :(得分:1)

尝试打开对话框时遇到相同的错误,我在这里找到了解决方法:github flutter issues。具体来说,我遵循发布者的建议,即创建一个GlobalKey并将其与Scaffold小部件关联,并在创建对话框时使用该键的上下文。就我而言,我有一个可全局访问的对象,该对象包含GlobalKey

MyGlobals myGlobals;
class MyGlobals {
  GlobalKey _scaffoldKey;
  MyGlobals() {
    _scaffoldKey = GlobalKey();
  }
  GlobalKey get scaffoldKey => _scaffoldKey;
}

Scaffold小部件构造函数调用中:

Scaffold(
  appBar: ...,
  body: ...,
  drawer: ...,
  key: myGlobals.scaffoldKey,
)

showDialog通话中:

showDialog<String>(
  barrierDismissible: ...,
  builder: ...,
  context: myGlobals.scaffoldKey.currentContext,
);

答案 3 :(得分:1)

尝试一下

为对话框提供不同的上下文名称

class User extends Authenticatable
{
    use Notifiable;

    protected $fillable = [
        'name',
        'first_name',
        'last_name',
        'email',
        'password',
        'activated',
        'token',
        'signup_ip_address',
        'signup_confirmation_ip_address',
        'signup_sm_ip_address',
        'admin_ip_address',
        'updated_ip_address',
        'deleted_ip_address',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function hasRole(String $roleName)
    {
        return $this->roles()->where('name', $roleName)->exists();
    }

    public function roles()
    {
        return $this->belongsToMany('App\Models\Role');
    }

    public function addRole(String $roleName)
    {
        $role = Role::where('name', $roleName)->first();

        if ($role) $this->roles()->save($role);
    }
}

答案 4 :(得分:0)

您正在尝试访问可能不可用的上下文。发生这种情况是因为您已将Dialog分配给var,然后使用了不同的上下文(对话框构建器中的上下文)。

要么直接在构建器中的return之后创建对话框,要么使其成为返回Dialog并传递一个BuildContext参数的方法。

Widget myDialog(BuildContext context) => Dialog(/*your dialog here*/);

这也是更方便的Flutter练习。您应该使用返回小部件的方法,而不是将其分配给变量。

答案 5 :(得分:0)

尝试一下:

    Future<AlertDialog> myDialog(BuildContext context) {
    return showDialog<AlertDialog>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: Container(
            margin: EdgeInsets.all(8.0),
            child: Form(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  TextFormField(
                    decoration: InputDecoration(
                        labelText: "Insira o número de telefone",
                        border: OutlineInputBorder(
                            borderRadius:
                                BorderRadius.all(Radius.circular(2.0)))),
                  ),
                ],
              ),
            ),
          ),
          actions: <Widget>[
            FlatButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: Text("Cancelar")),
            FlatButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: Text("Aceitar"))
          ],
        );
      },
    );
  }

答案 6 :(得分:0)

声明全局变量

    final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

然后在小部件构建的支架上注册密钥,例如

    @override
    Widget build(BuildContext context) {
     return Scaffold(
       key: _scaffoldKey,
       ...

然后在对话框上

show(BuildContext context){

var dialog = Dialog(
  child: Container(
    margin: EdgeInsets.all(8.0),
    child: Form(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          TextFormField(
            decoration: InputDecoration(
                labelText: "Insira o número de telefone",
                border: OutlineInputBorder(
                    borderRadius: BorderRadius.all(Radius.circular(2.0)))),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              FlatButton(
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                  child: Text("Cancelar")),
              FlatButton(
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                  child: Text("Aceitar"))
            ],
          )
        ],
      ),
    ),
  ),
);

将该支架上下文传递给showDialog方法

showDialog(context: _scaffoldKey.currentContext ,builder: (context){
  return dialog;
 });
}

答案 7 :(得分:-2)

我设法通过注释framework.dart文件中的某些行来解决此问题。

第3249行

 bool _debugCheckStateIsActiveForAncestorLookup() {
    assert(() {
      if (_debugLifecycleState != _ElementLifecycle.active) {
        // throw FlutterError(
        //   'Looking up a deactivated widget\'s ancestor is unsafe.\n'
        //   'At this point the state of the widget\'s element tree is no longer '
        //   'stable. To safely refer to a widget\'s ancestor in its dispose() method, '
        //   'save a reference to the ancestor by calling inheritFromWidgetOfExactType() '
        //   'in the widget\'s didChangeDependencies() method.\n'
        // );
      }
      return true;
    }());
    return true;
  }

希望这会有所帮助。 :D