#flutter #dart
#flutter #dart
Вопрос:
Я хочу сохранить значение предпочтения общего доступа в переменной класса, но оно вообще не работает, значение не сохраняется в переменной. вот мой код, в основном я хочу сохранить в переменную _uid
, но когда я обращаюсь к ней в своем пользовательском интерфейсе, она печатает «»..
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class User with ChangeNotifier {
FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
Firestore _firestore = Firestore.instance;
bool _loggedIn = false;
bool get loggedIn => _loggedIn;
String _uid = "";
String get uid => _uid;
User() {
getPrefState().then((val) {
// do some operation
_uid = val.toString() ?? "test";
});
//init();
}
Future init() async {
//var data;
//_uid = getPrefState();
/*SharedPreferences.getInstance().then((value) => {
_uid = value.getString("uid") ?? "d",
data = "dsdasd",
});*/
/*try {
SharedPreferences prefs = await SharedPreferences.getInstance();
_uid = data;
} catch (err) {
//pass.
}*/
//var uid = prefs.getString("uid") ?? "d";
/*if (uid != null) {
_loggedIn = true;
}*/
//_uid = "dsd";
//notifyListeners();
}
Future<String> getPrefState() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
//Return String
String stringValue = prefs.getString('uid') ?? "test";
return stringValue;
}
Future<void> saveId(uid) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("uid", uid);
}
Future<void> saveUserInDocument(String uid, String name, String sap) {
_firestore.collection("users").document(uid).setData({
"name": name,
"sap": sap,
'role': "student",
});
}
Future<FirebaseUser> getCurrentUser() async {
return await _firebaseAuth.currentUser();
}
// user signup.
Future<void> signup(
String email, String password, String name, String sap) async {
FirebaseUser user = (await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password))
.user;
if (user != null) {
saveUserInDocument(user.uid, name, sap);
saveId(user.uid);
_loggedIn = true;
notifyListeners();
}
}
/// user login
Future<void> login(String email, String password) async {
FirebaseUser user = (await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password))
.user;
//if (user != null) {
saveId(user.uid);
_loggedIn = true;
notifyListeners();
//}
}
/// User logout
Future<void> logout() async {
_firebaseAuth.signOut();
saveId(null);
_loggedIn = false;
notifyListeners();
}
/// reset user password
Future<void> resetPassword(String email) async {
await _firebaseAuth.sendPasswordResetEmail(email: email);
}
}
Вот мой класс пользовательского интерфейса, в котором я хочу его использовать
user.uid
import "package:flutter/material.dart";
import 'package:riphahwebresources/data/User.dart';
import 'package:riphahwebresources/pages/auth/login_ui.dart';
import 'package:shared_preferences/shared_preferences.dart';
class WebResourceAppDrawer extends StatefulWidget {
@override
_WebResourceAppDrawerState createState() => _WebResourceAppDrawerState();
}
class _WebResourceAppDrawerState extends State<WebResourceAppDrawer> {
User user = User();
@override
Widget build(BuildContext context) {
List<Widget> children = [];
children.add(
ListTile(
leading: Icon(Icons.home),
title: Text("Home"),
),
);
if (user.loggedIn) {
children.add(ListTile(
leading: Icon(Icons.people),
title: Text("Profile"),
onTap: () => {
Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginUi()))
},
));
children.add(ListTile(
leading: Icon(Icons.people),
title: Text("Logout"),
onTap: () => {
Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginUi()))
},
));
} else {
children.add(ListTile(
leading: Icon(Icons.people),
title: Text(user.uid),
onTap: () => {
Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginUi()))
},
));
}
return Drawer(
child: ListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
DrawerHeader(
child: Text("Menu"),
),
...children,
],
),
);
}
}
Вы можете видеть из метода init
, я пробую разные вещи, но idk у меня ничего не работает.
Большое вам спасибо.
Ответ №1:
При использовании ChangeNotifier
вам необходимо вызвать notifyListeners
, чтобы распространить изменение на ваш класс пользовательского интерфейса:
notifyListeners()
. Вызывайте этот метод каждый раз, когда модель изменяется таким образом, что может изменить пользовательский интерфейс вашего приложения.
Документы Flutter по управлению состоянием
В качестве напоминания вам понадобятся следующие 3 вещи, чтобы заставить управление состоянием работать:
-
Настройте класс, который
extends ChangeNotifier
(который вы сделали, но просто заменитеwith
наextends
) -
Добавьте a
ChangeNotifierProvider
над виджетом, где вам требуется значение (т. Е. Над вашимWebResourceAppDrawer
виджетом пользовательского интерфейса) -
Теперь получите доступ
User
, обернув виджет пользовательского интерфейса сConsumer<User>
Вот как будет выглядеть полный минимальный пример:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: Center(
child:
ChangeNotifierProvider(create: (_) => User(), child: UI()))),
// 'UI' can now access the newly created User() since it's a
// child of ChangeNotifierProvider
);
}
}
class UI extends StatefulWidget {
@override
_UIState createState() => _UIState();
}
class _UIState extends State<UI> {
@override
Widget build(BuildContext context) {
return Container(
child: Consumer<User>(
builder: (context, user, child) => Text("User ${user.uid}")),
// This is how user can be accessed within UI
);
}
}
class User extends ChangeNotifier {
String _uid = "(empty)";
String get uid => _uid;
User() {
getPrefState().then((val) {
_uid = val;
notifyListeners(); // this call triggers a rebuild of UI
});
}
getPrefState() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('uid');
}
}