繁体   English   中英

flutter 错误:此小部件已卸载,因此 State 不再具有上下文(应被视为已失效)

[英]flutter error: This widget has been unmounted, so the State no longer has a context (and should be considered defunct)

当我在我的手机号码错误时单击登录按钮时,然后打开一个错误对话框,然后当我在对话框上单击确定时,我得到了这个错误。

我收到这条消息

此小部件已被卸载,因此 State 不再具有上下文(应被视为已失效)

考虑在“处理”期间取消任何活动工作,或使用“已安装”吸气剂来确定 State 是否仍处于活动状态。

class _LoginPageState extends State<LoginPage> {
  final GlobalKey<FormState> _formKey = GlobalKey();

  TextEditingController _mobileController = new TextEditingController();
  // TextEditingController _nameController = new TextEditingController();
  // TextEditingController _emailController = new TextEditingController();
  TextEditingController _passwordController = new TextEditingController();

  Map<String, String> _authData = {
    'user_name': '',
    'user_email': '',
    'username': '',
    'password': ''
  };

  Future _submit() async {
    print('aa' + _authData['username']);
    if (!_formKey.currentState.validate()) {
   

      return;
    }
    _formKey.currentState.save();
    try {
      await Provider.of<Auth>(context, listen: false).login(
          _authData['user_name'],
          _authData['user_email'],
          _authData['username'],
          _authData['password']);


      print('authData_username' + _authData['username']);
      print('authData_password' + _authData['password']);
    } on HttpException catch (e) {
      // } catch (e) {
      var errorMessage = 'Authentication Failed';
      if (e.toString().contains('Entered wrong mobile number!')) {
        errorMessage = 'Entered wrong mobile number!';
        print(errorMessage);
        _showerrorDialog(errorMessage);
      } else if (e.toString().contains('Entered wrong password!')) {
        errorMessage = 'Entered wrong password!';
        _showerrorDialog(errorMessage);
      }
    } catch (error) {
      var errorMessage = 'Please try again later';
      _showerrorDialog(errorMessage);
    }
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: ListView(
          children: <Widget>[
            Container(
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height / 3.5,
              decoration: BoxDecoration(
                  gradient: LinearGradient(
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                      
                      colors: myGradient2),
                  borderRadius:
                      BorderRadius.only(bottomLeft: Radius.circular(90))),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Spacer(),
                  Align(
                    alignment: Alignment.center,
                    child: Icon(
                      Icons.person,
                      size: 90,
                      color: kWhite,
                    ),
                  ),
                  Spacer(),
                  Align(
                    alignment: Alignment.bottomRight,
                    child: Padding(
                      padding: const EdgeInsets.only(bottom: 32, right: 32),
                      child: Text(
                        'Login',
                        style: TextStyle(color: kWhite, fontSize: 18),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Container(
              height: MediaQuery.of(context).size.height / 2,
              width: MediaQuery.of(context).size.width,
              padding: EdgeInsets.only(top: 62),
              child: Form(
                key: _formKey,
                child: Column(
                  children: <Widget>[
                    Container(
                      width: MediaQuery.of(context).size.width / 1.2,
                      // height: 45,
                      child: TextFormField(
                        keyboardType: TextInputType.name,
                        autofocus: false,
                        decoration: InputDecoration(
                          hintText: 'Username.',
                          contentPadding:
                              EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(32.0)),
                        ),
                        validator: (input) =>
                            input.length > 10 || input.length < 10
                                ? "Mobile Number should be valid"
                                : null,
                        controller: _mobileController,
                        onSaved: (value) {
                          _authData['username'] = value;
                        },
                        // maxLength: 10,
                      ),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    Container(
                      width: MediaQuery.of(context).size.width / 1.2,
                      // height: 45,
                      child: TextFormField(
                        keyboardType: TextInputType.text,
                        autofocus: false,
                        obscureText: true,
                        decoration: InputDecoration(
                          hintText: 'Password',
                          contentPadding:
                              EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(32.0)),
                        ),
                        validator: (input) => input.length < 3
                            ? "Password should be more than 3 characters"
                            : null,
                        controller: _passwordController,
                        onSaved: (value) {
                          _authData['password'] = value;
                        },
                      ),
                    ),
                    Align(
                      alignment: Alignment.centerRight,
                      child: Padding(
                        padding: const EdgeInsets.only(top: 16, right: 32),
                        child: Text(
                          'Forgot Password ?',
                          style: TextStyle(color: Colors.grey),
                        ),
                      ),
                    ),
                    Spacer(),
                    InkWell(
                      onTap: () {
                        _submit();
                      },
                      child: Container(
                        height: 45,
                        width: MediaQuery.of(context).size.width / 1.2,
                        decoration: BoxDecoration(
                            gradient: LinearGradient(
                              colors: myGradient2,
                            ),
                            borderRadius:
                                BorderRadius.all(Radius.circular(50))),
                        child: Center(
                          child: Text(
                            'Login'.toUpperCase(),
                            style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            SizedBox(
              height: 50,
            ),
            InkWell(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text("Dnon't have an account ?"),
                  Text(
                    "Sign Up",
                    style: TextStyle(color: kGreen),
                  ),
                ],
              ),
              onTap: () {
                // Navigator.pushNamed(context, '/signup');
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SignupPage()),
                );
              },
            ),
          ],
        ),
      ),
    );
  }

  void _showerrorDialog(String message) {
    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text(
          'An Error Occurs',
          style: TextStyle(color: Colors.blue),
        ),
        content: Text(message),
        actions: <Widget>[
          FlatButton(
              child: Text('Okay'), onPressed: () => Navigator.of(mounted).pop())
        ],
      ),
    );
  }
}

尝试使用

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

而不是 Navigator.of(mounted).pop()) 来关闭对话框窗口。

This widget has been unmounted, so the State no longer has a context (and should be considered defunct). Consider canceling any.
Ans:

    if (mounted) {
      ...
    }

这是因为您没有处置或取消任何订阅或控制器。TRr 处置或取消订阅或控制器。

在您的 MaterialApp 小部件中添加一个 GlobalKey 以保留 state,然后使用navigatorKey.currentState?.pop()弹出屏幕。 你也可以使用navigatorKey.currentState?.pushNamed(routeName) , pushReplacementNamed ...

 final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

@override
  Widget build(BuildContext context) {
   
    return MaterialApp(
                  ...
                  navigatorKey: navigatorKey,
                );
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM