繁体   English   中英

Flutter - 使用 SharedPreferences 保持用户登录

[英]Flutter - Using SharedPreferences to keep user logged in

所以我目前正在开发一个考勤应用程序,但尚未了解sharedpreferences工作原理,所以只要用户没有手动注销,我就很难让用户保持登录状态。 更令人困惑的是,我的应用程序使用 PHP API 作为后端。

这是main.dart的代码

      void main() async {
        WidgetsFlutterBinding.ensureInitialized();
        SharedPreferences preferences = await SharedPreferences.getInstance();
        var lg_username = preferences.getString('lg_username');
        var lg_password = preferences.getString('lg_password');
        bool? isLoggedin = preferences.getBool('isLoggedin');
        user.lg_username = lg_username;
        user.lg_password = lg_password;
        user.lat = 0;
        user.long = 0;
        print(user.lg_username);
        print(user.lg_password);
        // runApp(MaterialApp(home: lg_username == null ? const MyApp() : const HomePage()));
        runApp(MyApp());
      }

      class MyApp extends StatelessWidget {
        const MyApp({Key? key}) : super(key: key);

        @override
        Widget build(BuildContext context) {
          return const MaterialApp(
            // debugShowCheckedModeBanner: false,
            home: Splash(),
          );
        }
      }

如果用户已经登录,则Splash()中的此 function 将跳过登录页面

    _navigatetohome() async {
      await Future.delayed(const Duration(milliseconds: 1500), () {
        if (user.lg_username == null){
          Navigator.pushReplacement(
            context, MaterialPageRoute(builder: (context) => const LoginPage()));
        }else{
          Navigator.pushReplacement(
            context, MaterialPageRoute(builder: (context) => const HomePage()));
        }
      });

_login function 在登录页面应该保存数据在user.dart

  Future _login() async {
      if (unameController.text == username && passController.text == password) {
        Fluttertoast.showToast(
          msg: 'Login Successful',
          backgroundColor: Colors.green,
          textColor: Colors.white,
          toastLength: Toast.LENGTH_SHORT,
        );
        SharedPreferences preferences = await SharedPreferences.getInstance();
        preferences.setString('lg_username', unameController.text);
        preferences.setString('lg_password', passController.text);
        preferences.setBool('isLoggedin', true);
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => const HomePage(),
          ),
        );
      } else {
        Fluttertoast.showToast(
          msg: 'Username or Password is invalid!',
          backgroundColor: Colors.red,
          textColor: Colors.white,
          toastLength: Toast.LENGTH_SHORT,
        );
      }
    }

user.dart我在其中存储了要发送到 API 的用户登录数据

    class user{
      static String? lg_username;
      static String? lg_password;
      static bool? isLoggedin;
      static double lat = 0;
      static double long = 0;
    }

TodayPage()是应用程序的主页面,登录用户将在启动屏幕后立即被引导至此处。

    Future getUser() async {
      SharedPreferences preferences = await SharedPreferences.getInstance();
      setState(() {
        user.lg_username = preferences.getString('lg_username');
      });
    }

    Future displayLg_name() async {
      var url = Uri.http(
          "192.168.68.216", '/ump_attendance_2/username.php', {'q': '{http}'});
      var response = await http.post(url, body: {
        "lg_username": user.lg_username,
      });
      if (response.body.isNotEmpty) {
        return json.decode(response.body);
      }
    }

但是,它在上面的displayLg_name()中返回转换错误。 而且我的应用程序不会显示将从数据库中检索的用户名。 我以为我已经将它保存在user.dart但是当我在登录后再次尝试打开应用程序时,似乎 API 没有从我的应用程序中检索任何数据。 我该如何解决?

提前致谢

// This function should not be here, infact it is not necessary.
Future getUser() async {
      SharedPreferences preferences = await SharedPreferences.getInstance();
      setState(() {
        user.lg_username = preferences.getString('lg_username');
      });
    }

Future displayLg_name() async {
  var url = Uri.http(
      "192.168.68.216", '/ump_attendance_2/username.php', {'q': '{http}'});
  var response = await http.post(url, body: {
    "lg_username": user.lg_username,
  });
  if (response.body.isNotEmpty) {
    return json.decode(response.body);
  }
}

这是你可以做到的,它会工作得很好

Future displayLg_name() async {
      SharedPreferences preferences = await SharedPreferences.getInstance();
      setState(() {
        user.lg_username = preferences.getString('lg_username');
      });
  var url = Uri.http(
      "192.168.68.216", '/ump_attendance_2/username.php', {'q': '{http}'});
  var response = await http.post(url, body: {
    "lg_username": user.lg_username,
  });
  if (response.body.isNotEmpty) {
    return json.decode(response.body);
  }
}

Using an entore function to set the state before you use another function to use the value from the previous function.

您可以触发一个 function,它将触发 state 更改并按预期运行。

如果您坚持按原样使用您的代码,那么实际上就是这样。

    Future<String> getUser() async {
          SharedPreferences preferences = await SharedPreferences.getInstance();
          setState(() {
            user.lg_username = preferences.getString('lg_username');
          });

return user.lg_username;
        }
    
Future displayLg_name() async {
  var url = Uri.http(
      "192.168.68.216", '/ump_attendance_2/username.php', {'q': '{http}'});
  var response = await http.post(url, body: {
    "lg_username": await getUser(),
  });
  if (response.body.isNotEmpty) {
    return json.decode(response.body);
  }
}

但在我看来,这是 go 的低效方法。

暂无
暂无

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

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