![](/img/trans.png)
[英]How to Store a User ID after Login and access from another page in flutter?
[英]How to store a User id or "key" after login and access from anywhere in Flutter app?
我正在嘗試確定登錄后存儲和訪問我的 Flutter 應用程序的用戶 object 的最佳方式。 目前還沒有真正的身份驗證。 因此,當“用戶”登錄時,它只需檢查 json 文件中的虛擬用戶名和密碼。 我唯一想知道的是從應用程序的任何位置存儲和訪問我的用戶 ID 的適當方式是什么? 每次屏幕更改時,我都將它作為路由參數傳遞,但這似乎有點矯枉過正。 最合適的方法是什么? 只需創建一個 globals.dart 文件並將用戶 ID 添加為變量?
json 中的用戶示例:
{
"id" : 5,
"fName" : "John",
"lName" : "Doe",
"position" : "Software Developer",
"username" : "jdoe",
"password" : "jdoepass",
"imageUrl": "assets/images/profile_pictures/profilePicture.png",
"email" : "jdoe@onepartner.com",
"location" : "Big Software Company"
}
登錄.dart:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../utils/opWidgets.dart';
import '../utils/fetchJson.dart';
import '../../entities/User.dart';
/* Description: Login screen widget and functions to handle fetching user json */
class LoginPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _LoginPageState();
}
}
class _LoginPageState extends State<LoginPage> {
List<User> _userList = []; //used to represent the list items in the UI
final userTxtController = TextEditingController();
final passTxtController = TextEditingController();
User _currentUser;
bool _invalidUserMsgVisible = false;
@override
initState() {
//initializes data before build() is called
//Use this method to initialize data that will be displayed
//initialize list items using function that fetches/converts json
fetchUsers().then((value) {
setState(() {
_userList.addAll(value);
});
});
super.initState();
}
@override
void dispose() {
//releases memory
userTxtController.dispose();
passTxtController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: GestureDetector(
//Makes the keyboard collapse when the scaffold body is tapped
onTap: () => FocusScope.of(context).unfocus(),
child: _layoutDetails(),
),
);
}
//This widget determines the layout of the widgets _logo() and _loginForm() based on the screen's orientation
Widget _layoutDetails() {
Orientation orientation = MediaQuery.of(context).orientation;
if (orientation == Orientation.portrait) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_logo(),
_loginForm(),
],
);
} else {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_logo(),
Container(
width: MediaQuery.of(context).size.width / 1.8,
height: MediaQuery.of(context).size.height,
child: _loginForm(),
),
],
);
}
}
Widget _logo() {
return Container(
width: 225,
child: Image.asset('assets/images/logos/OPNewLogo.png'),
);
}
Widget _loginForm() {
return Container(
width: double.infinity,
padding: EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Visibility(
visible: _invalidUserMsgVisible,
child: Text(
'Username or password is invalid',
style: GoogleFonts.montserrat(color: Colors.red, fontSize: 14),
),
),
SizedBox(height: 5),
Container(
//margin: EdgeInsets.symmetric(horizontal: 10),
width: 500,
child: opTextField('Username', false, userTxtController),
),
SizedBox(height: 20),
Container(
//margin: EdgeInsets.symmetric(horizontal: 10),
width: 500,
child: opTextField('Password', true, passTxtController),
),
SizedBox(height: 20),
Container(
width: 500,
height: 40,
padding: EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () => _verifyLogin(
userTxtController.text.toString().trim(),
passTxtController.text.toString(),
),
child: Text(
'LOGIN',
style: GoogleFonts.montserrat(
fontSize: 16,
letterSpacing: 1.5,
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
primary: Theme.of(context).accentColor,
elevation: 3,
),
),
),
SizedBox(height: 5),
Container(
width: 500,
height: 40,
padding: EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () => {
Navigator.pop(context),
},
child: Text(
'REGISTER',
style: TextStyle(
fontSize: 16,
letterSpacing: 2.2,
color: Theme.of(context).shadowColor,
fontWeight: FontWeight.w500),
),
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(
color: Theme.of(context).primaryColorDark,
),
),
primary: Colors.white,
),
),
),
Container(
child: TextButton(
autofocus: false,
clipBehavior: Clip.none,
child: Text(
'Forgot Password',
style: GoogleFonts.montserrat(
fontSize: 15,
color: Theme.of(context).shadowColor,
decoration: TextDecoration.underline,
),
),
onPressed: () =>
Navigator.pushNamed(context, resetPasswordPageRoute),
),
),
],
),
);
}
//Function to check the username and password input against the list of user objects
void _verifyLogin(String username, String password) {
bool _validUser = false;
//Loop through fetched user objects and check for a match
for (var user in _userList) {
if (username == user.username && password == user.password) {
_validUser = true;
_currentUser = user; //Set the current user object
break;
}
}
//If a valid user was found, pop login screen and push home screen
if (_validUser) {
Navigator.popAndPushNamed(
context,
homePageRoute,
arguments:
_currentUser, //Pass the current user object to the home screen
);
} else {
//if no valid user was found, make error message text visible
setState(() {
_invalidUserMsgVisible = true;
});
}
}
}
您可以使用 static 和 class 將此數據保存在整個應用程序中
class SaveData{
static int id
setId(int id1){
id = id1;
}
getId(){
return id;
}
}
我猜您最終會希望通過超時進行用戶身份驗證,因此需要一種在用戶超時時通知應用程序的方法。 一個很好的方法是使用ChangeNotifierProvider
- 有很好的教程,例如Simple app state management 。 即使在您需要通知之前,使用此機制共享您的 state 也是一個好主意。
這是示例代碼:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// User class
class User {
final String username;
User(this.username);
String toString() => username;
}
// AuthService has all authentication logic, notifies listeners
class AuthService with ChangeNotifier {
User _user;
User get user => _user;
Future<void> _authenticate(String email, String password,
[String name]) async {
// This is where you authenticate or register the user, and update the state
_user = User("dummy");
return Future<void>(() {});
}
Future<void> register(String name, String email, String password) async {
return _authenticate(email, password, name);
}
Future<void> login(String email, String password) async {
return _authenticate(email, password);
}
Future<void> logout() async {
_user = null;
notifyListeners();
return Future<void>(() {});
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Put all your ChangeNotifierProviders above MaterialApp
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => AuthService(),
),
],
child: MaterialApp(
title: 'Test App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: AuthTest(),
),
);
}
}
class AuthTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
// Login user
TextButton(
child: Text("Login"),
onPressed: () async {
await Provider.of<AuthService>(context, listen: false)
.login("email", "password");
},
),
// Logout user
TextButton(
child: Text("Logout"),
onPressed: () async {
await Provider.of<AuthService>(context, listen: false).logout();
},
),
// Child form
TextButton(
child: Text("Form"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AuthFormTest()),
);
},
),
]),
);
}
}
class AuthFormTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Get AuthService, will rebuild when it notifies listeners
var authService = Provider.of<AuthService>(context);
return Scaffold(
appBar: AppBar(
title: Text('User'),
),
body: Center(child: Text('User: ${authService.user}')),
);
}
}
您可以使用shared_preferences庫將您的 id 或 key 保存為 key-value 並在任何地方訪問:
保存:
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt('id', YOUR_ID);
讀書:
prefs.getInt('id');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.