【问题标题】:Showing a snackbar in Flutter在 Flutter 中显示一个小吃店
【发布时间】:2020-04-07 03:13:11
【问题描述】:

我正在处理我项目的登录部分,我有一个带有电子邮件和密码的表单以及一个登录按钮,一切正常,它正在连接到 Firebase。它向我发送成功或错误的结果。我想问的是,我想在小吃店显示错误,我已经尝试了一整天,但它不起作用。任何人都可以请帮助!我得到的错误信息如下,

FlutterError(查找已停用小部件的祖先是不安全的。 此时小部件的元素树的状态不再稳定。 要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用 inheritFromWidgetOfExactType() 来保存对祖先的引用。)

这是代码

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:inclass/screens/authentication/signup.dart';
import 'package:inclass/screens/home/dashboard.dart';
import 'package:inclass/services/auth.dart';
import 'package:inclass/shared/loading.dart';
import 'package:inclass/widgets/logo.dart';

class Signin extends StatefulWidget {
  @override
  _SigninState createState() => _SigninState();
}

class _SigninState extends State<Signin> {
  bool _obscureText = true;
  final AuthService _auth = AuthService();
  final _formkey = GlobalKey<FormState>();
  bool loading = false;

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

  String email = '';
  String password = '';
  String error = '';

  @override
  Widget build(BuildContext context) {
    return loading
        ? Loading()
        : Scaffold(
            key: _scaffoldKey,
            backgroundColor: Colors.white,
            body: Builder(
              builder: (context) => ListView(children: <Widget>[
                Form(
                  key: _formkey,
                  child: Column(
                    children: <Widget>[
                      Logo(),
                      SizedBox(
                        height: 20.0,
                      ),
                      Stack(children: <Widget>[
                        Image(
                          height: 200.0,
                          width: MediaQuery.of(context).size.width,
                          image: AssetImage("assets/images/move.png"),
                          fit: BoxFit.cover,
                        ),
                        Positioned(
                            bottom: 20.0,
                            right: 60.0,
                            child: Text(
                              'Sign In',
                              style: TextStyle(
                                  color: Color(0xff7E8E9D),
                                  fontSize: 22.0,
                                  fontFamily: 'Poppins'),
                              textAlign: TextAlign.center,
                            )),
                        Positioned(
                          bottom: 5.0,
                          right: 80.0,
                          child: Text(
                            "As",
                            style: TextStyle(
                                color: Color(0xff7E8E9D),
                                fontSize: 15.0,
                                fontFamily: 'Poppins'),
                            textAlign: TextAlign.center,
                          ),
                        )
                      ]),
                      Padding(
                        padding: const EdgeInsets.only(
                            top: 20.0, left: 15.0, right: 15.0),
                        child: Center(
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                            children: <Widget>[
                              Container(
                                width: MediaQuery.of(context).size.width / 3,
                                height: 80.0,
                                decoration: new BoxDecoration(
                                  //border: new Border.all(width: 1.0, color: Colors.black),
                                  //shape: BoxShape.circle,
                                  color: Colors.white,
                                  boxShadow: <BoxShadow>[
                                    // BoxShadow(
                                    //   color: Colors.grey,
                                    //   offset: Offset(1.0, 15.0),
                                    //   blurRadius: 64.0,
                                    // ),
                                  ],
                                ),
                                // color: Colors.blue,
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    Icon(
                                      FontAwesomeIcons.graduationCap,
                                      color: Color(0xffB57E20),
                                      size: 22.0,
                                    ),
                                    Padding(
                                      padding:
                                          const EdgeInsets.only(left: 15.0),
                                      child: Text(
                                        "Student",
                                        style: TextStyle(
                                            color: Color(0xffB57E20),
                                            fontSize: 17.0,
                                            fontFamily: 'Poppins'),
                                      ),
                                    )
                                  ],
                                ),
                              ),
                              Container(
                                width: 1.0,
                                height: 60.0,
                                decoration: BoxDecoration(
                                  border: Border(
                                    right: BorderSide(color: Colors.black54),
                                  ),
                                ),
                              ),
                              Container(
                                width: MediaQuery.of(context).size.width / 3,
                                height: 80.0,
                                decoration: new BoxDecoration(
                                  //border: new Border.all(width: 1.0, color: Colors.black),
                                  //shape: BoxShape.circle,
                                  color: Colors.white,
                                  boxShadow: <BoxShadow>[
                                    // BoxShadow(
                                    //   color: Colors.grey,
                                    //   offset: Offset(1.0, 15.0),
                                    //   blurRadius: 64.0,
                                    // ),
                                  ],
                                ),
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    Icon(
                                      FontAwesomeIcons.chalkboardTeacher,
                                      color: Color(0xff00315C),
                                      size: 22.0,
                                    ),
                                    Padding(
                                      padding:
                                          const EdgeInsets.only(left: 15.0),
                                      child: Text(
                                        "Teacher",
                                        style: TextStyle(
                                            color: Color(0xff00315C),
                                            fontSize: 17.0,
                                            fontFamily: 'Poppins'),
                                      ),
                                    )
                                  ],
                                ),
                              )
                            ],
                          ),
                        ),
                      ),
                      Container(
                        child: Padding(
                          padding: const EdgeInsets.only(
                              left: 20.0, right: 20.0, top: 40.0),
                          child: TextFormField(
                            onChanged: (val) {
                              setState(() => email = val);
                            },
                            validator: (val) =>
                                val.isEmpty ? "Email can't be Empty" : null,
                            // textAlign: TextAlign.center,
                            keyboardType: TextInputType.emailAddress,
                            // autofocus: true,
                            decoration: InputDecoration(
                                labelText: "Email",
                                contentPadding:
                                    EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
                                border: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(12.0),
                                    borderSide:
                                        BorderSide(color: Color(0xff00315C))),
                                suffixIcon: Icon(Icons.mail)),
                          ),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(
                            top: 15.0, left: 20.0, right: 20.0, bottom: 20.0),
                        child: TextFormField(
                          obscureText: _obscureText,
                          onChanged: (val) {
                            setState(() => password = val);
                          },
                          validator: (val) => val.length < 6
                              ? "Password Must be 6+ Char"
                              : null,
                          // textAlign: TextAlign.center,
                          // autofocus: true,
                          decoration: InputDecoration(
                              labelText: "Password",
                              contentPadding:
                                  EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
                              border: OutlineInputBorder(
                                  borderRadius: BorderRadius.circular(12.0),
                                  borderSide:
                                      BorderSide(color: Color(0xff00315C))),
                              suffixIcon: GestureDetector(
                                onTap: () {
                                  setState(() {
                                    _obscureText = !_obscureText;
                                  });
                                },
                                child: Icon(
                                  _obscureText
                                      ? Icons.visibility
                                      : Icons.visibility_off,
                                  semanticLabel: _obscureText
                                      ? 'show password'
                                      : 'hide password',
                                ),
                              )),
                        ),
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          Padding(
                            padding: const EdgeInsets.only(left: 20.0),
                            child: FlatButton(
                              child: Text("Forgot Password?",
                                  style: TextStyle(color: Colors.grey)),
                              onPressed: () {},
                            ),
                          ),
                          Padding(
                            padding: const EdgeInsets.only(right: 25.0),
                            child: OutlineButton(
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10),
                              ),
                              highlightedBorderColor: Color(0xffB57E20),
                              borderSide: BorderSide(color: Color(0xffB57E20)),
                              onPressed: () async {
                                if (_formkey.currentState.validate()) {
                                  setState(() => loading = true);
                                  dynamic result =
                                      await _auth.signInWithEmailAndPassword(
                                          email, password);
                                  if (result == null) {
                                    setState(() {
                                      error = 'Could not sign in';
                                      loading = false;
                                    });
                                    _showToast(context,error);
                                    print(error);
                                  } else {
                                    // Navigator.push(
                                    //     context,
                                    //     MaterialPageRoute(
                                    //         builder: (_) => DashBoard()));
                                    print("Succeed");
                                  }
                                }
                              },
                              padding: EdgeInsets.only(
                                  left: 30.0,
                                  right: 15.0,
                                  top: 12.0,
                                  bottom: 12.0),
                              color: Colors.white,
                              child: Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceEvenly,
                                children: <Widget>[
                                  Text(
                                    "Next",
                                    style: TextStyle(
                                        color: Color(0xffB57E20),
                                        fontSize: 17.0,
                                        fontFamily: 'Poppins'),
                                  ),
                                  Padding(
                                    padding: const EdgeInsets.only(
                                        left: 10.0, top: 2.0),
                                    child: Icon(Icons.navigate_next,
                                        color: Color(0xffB57E20), size: 30.0),
                                  )
                                ],
                              ),
                            ),
                          )
                        ],
                      ),
                      Padding(
                        padding: const EdgeInsets.all(28.0),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Text("Not Registered Yet?",
                                style: TextStyle(
                                    color: Colors.grey,
                                    fontSize: 15.0,
                                    fontFamily: 'Poppins')),
                            SizedBox(
                              width: 10.0,
                            ),
                            GestureDetector(
                              onTap: () => Navigator.push(context,
                                  MaterialPageRoute(builder: (_) => SignUp())),
                              child: Text("Sign Up",
                                  style: TextStyle(
                                      color: Color(0xff00315C),
                                      fontSize: 15.0,
                                      fontFamily: 'Poppins')),
                            ),
                          ],
                        ),
                      )
                    ],
                  ),
                ),
              ]),
            ),
          );
  }

  void _showToast(BuildContext context,String error) {
    final scaffold = Scaffold.of(context);
    scaffold.showSnackBar(SnackBar(
      content: Text(error),
      duration: Duration(seconds: 2),
      action: SnackBarAction(
        onPressed: () {
          scaffold.hideCurrentSnackBar();
        },
        label: 'Okay',
      ),
    ));
  }
}

我的代码有点乱,我还没有重构它

【问题讨论】:

  • 我试过了。它不起作用

标签: flutter dart


【解决方案1】:

它与您的这部分代码有关 返回

loading
    ? Loading()
    : Scaffold(

当你点击下一步按钮时,你输入这样的代码来加载

setState(() => loading = true);

它会从 Widget 树中移除 Scaffold。当您尝试使用 _showToast 函数时,虽然您再次调用了 setState loading = false,但 Scaffold 尚未准备好并已移动到 Widget 树中,因此 Scaffold.of 无法获得您想要的正确结果。

所以我建议你如果要显示加载屏幕,你应该使用 Dialog 或 IndexedStack。

希望这可以解决您的问题。

【讨论】:

    猜你喜欢
    • 2016-03-13
    • 2016-04-01
    • 2018-09-27
    • 2020-02-16
    • 2018-05-04
    • 2020-05-18
    • 2020-05-22
    • 2022-10-08
    • 2018-11-29
    相关资源
    最近更新 更多