首页 > 解决方案 > Flutter 按下返回按钮再次从登录页面弹出先前的snackBar

问题描述

我在 Flutter 中有一个 LoginPage。登录后,它会显示一个带有“成功”或“失败..”的小快餐栏,如果密码错误,则导航到待办事项列表。

当我现在按下 Android 设备上的“返回”按钮时,它会导航回登录屏幕。但是,仍然弹出小吃栏并说“登录成功,正在重定向..”,而且我的文本字段没有清空并且仍然具有第一次登录时的值,为什么?这不应该发生,但我无法弄清楚为什么会这样......这是我的代码:

import 'package:flutter/material.dart';
import 'package:todoey_flutter/components/rounded_button.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:todoey_flutter/util/file_handler.dart';
import 'package:provider/provider.dart';

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  String username;
  String password;
  String hashedPW;
  // Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  var _nameController = TextEditingController();
  var _pwController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    CryptOid cy = Provider.of<CryptOid>(context, listen: true);
    FileHandler fh = Provider.of<FileHandler>(context, listen: true);
    return Scaffold(
      backgroundColor: Colors.white,
      body: Builder(
        builder: (BuildContext scaffoldBuildContext) {
          return Container(
            //inAsyncCall: isSpinning,
            child: Padding(
              padding: EdgeInsets.symmetric(horizontal: 34.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  /*
                Flexible(
                  child: Hero(
                    tag: 'logo',
                    child: Container(
                      height: 200.0,
                      child: Image.asset('images/logo.png'),
                    ),
                  ),
                ),*/
                  SizedBox(
                    height: 48.0,
                  ),
                  TextField(
                    controller: _nameController,
                    style: TextStyle(color: Colors.black54),
                    onChanged: (value) {
                      //Do something with the user input.
                      username = value.toLowerCase();
                    },
                    decoration: InputDecoration(
                      hintText: 'Enter your username',
                    ),
                  ),
                  SizedBox(
                    height: 8.0,
                  ),
                  TextField(
                    controller: _pwController,
                    obscureText: true,
                    style: TextStyle(color: Colors.black54),
                    onChanged: (value) {
                      //Do something with the user input.
                      password = value;
                    },
                    decoration: InputDecoration(
                      hintText: 'Enter your password',
                    ),
                  ),
                  SizedBox(
                    height: 24.0,
                  ),
                  RoundedButton(
                    title: 'Login',
                    colour: Colors.lightBlueAccent,
                    onPressed: () async {
                      Scaffold.of(scaffoldBuildContext).removeCurrentSnackBar();

                      print("user: $username, pw: $password");
                      if ((username != '' && username != null) && (password != '' && password != null)) {
                        SharedPreferences prefs = await SharedPreferences.getInstance();
                        // cy.test();
                        if ((username != '' && username != null) && prefs.containsKey(username)) {
                          hashedPW = prefs.getString(username);
                          bool decryptPW = await cy.deHash(hashedPW, password);
                          if (decryptPW) {
                            cy.setUsername(username);
                            fh.setUser(username);
                            prefs.setString('activeUser', username);

                            Scaffold.of(scaffoldBuildContext).showSnackBar(
                              SnackBar(
                                content: Text("Login successful! redirecting.."),
                              ),
                            );

                            Navigator.pushNamed(context, 'taskScreen');
                          } else {
                            Scaffold.of(scaffoldBuildContext).showSnackBar(
                              SnackBar(
                                content: Text("Wrong password for user $username!"),
                              ),
                            );
                          }
                        } else {
                          String hashedPW = await cy.hashPW(password);
                          prefs.setString('activeUser', username);
                          prefs.setString(username, hashedPW);
                          cy.setUsername(username);
                          fh.setUser(username);

                          Scaffold.of(scaffoldBuildContext).showSnackBar(
                            SnackBar(
                              content: Text("User created successful! redirecting.."),
                            ),
                          );
                          Navigator.pushNamed(context, 'taskScreen');

                          //prefs.setString(username, hashedPW);
                        }
                        _nameController.clear();
                        _pwController.clear();
                      } else {
                        Scaffold.of(scaffoldBuildContext).showSnackBar(
                          SnackBar(
                            content: Text("User and password may not be empty.."),
                          ),
                        );
                        _nameController.clear();
                        _pwController.clear();
                        return;
                      }
                    },
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

标签: flutterbackandroid-snackbarflutter-navigation

解决方案


您应该创建一个ScaffoldStateGlobalKey 然后将其分配给脚手架。

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

@override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      body: Container());
  }

使用密钥showSnackBar

void _showInSnackBar(String value) {
    _scaffoldKey.currentState
        .showSnackBar(new SnackBar(content: new Text(value)));
  }

因此,您的完整代码将如下所示:

import 'package:flutter/material.dart';
import 'package:todoey_flutter/components/rounded_button.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:todoey_flutter/util/file_handler.dart';
import 'package:provider/provider.dart';

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  String username;
  String password;
  String hashedPW;
  // Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  var _nameController = TextEditingController();
  var _pwController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    CryptOid cy = Provider.of<CryptOid>(context, listen: true);
    FileHandler fh = Provider.of<FileHandler>(context, listen: true);
    return Scaffold(
      key: _scaffoldKey,
      backgroundColor: Colors.white,
      body: Builder(
        builder: (BuildContext scaffoldBuildContext) {
          return Container(
            //inAsyncCall: isSpinning,
            child: Padding(
              padding: EdgeInsets.symmetric(horizontal: 34.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  /*
                Flexible(
                  child: Hero(
                    tag: 'logo',
                    child: Container(
                      height: 200.0,
                      child: Image.asset('images/logo.png'),
                    ),
                  ),
                ),*/
                  SizedBox(
                    height: 48.0,
                  ),
                  TextField(
                    controller: _nameController,
                    style: TextStyle(color: Colors.black54),
                    onChanged: (value) {
                      //Do something with the user input.
                      username = value.toLowerCase();
                    },
                    decoration: InputDecoration(
                      hintText: 'Enter your username',
                    ),
                  ),
                  SizedBox(
                    height: 8.0,
                  ),
                  TextField(
                    controller: _pwController,
                    obscureText: true,
                    style: TextStyle(color: Colors.black54),
                    onChanged: (value) {
                      //Do something with the user input.
                      password = value;
                    },
                    decoration: InputDecoration(
                      hintText: 'Enter your password',
                    ),
                  ),
                  SizedBox(
                    height: 24.0,
                  ),
                  RoundedButton(
                    title: 'Login',
                    colour: Colors.lightBlueAccent,
                    onPressed: () async {
                      _scaffoldKey.currentState.removeCurrentSnackBar();

                      print("user: $username, pw: $password");
                      if ((username != '' && username != null) &&
                          (password != '' && password != null)) {
                        SharedPreferences prefs =
                            await SharedPreferences.getInstance();
                        // cy.test();
                        if ((username != '' && username != null) &&
                            prefs.containsKey(username)) {
                          hashedPW = prefs.getString(username);
                          bool decryptPW = await cy.deHash(hashedPW, password);
                          if (decryptPW) {
                            cy.setUsername(username);
                            fh.setUser(username);
                            prefs.setString('activeUser', username);

                            _showInSnackBar("Login successful! redirecting..");

                            Navigator.pushNamed(context, 'taskScreen');
                          } else {
                            _showInSnackBar(
                                "Wrong password for user $username!");
                          }
                        } else {
                          String hashedPW = await cy.hashPW(password);
                          prefs.setString('activeUser', username);
                          prefs.setString(username, hashedPW);
                          cy.setUsername(username);
                          fh.setUser(username);

                          _showInSnackBar(
                              "User created successful! redirecting..");
                          Navigator.pushNamed(context, 'taskScreen');

                          //prefs.setString(username, hashedPW);
                        }
                        _nameController.clear();
                        _pwController.clear();
                      } else {
                        _showInSnackBar("User and password may not be empty..");
                        _nameController.clear();
                        _pwController.clear();
                        return;
                      }
                    },
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }

  void _showInSnackBar(String value) {
    _scaffoldKey.currentState
        .showSnackBar(new SnackBar(content: new Text(value)));
  }
}

推荐阅读