[英]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.