Le code suivant fait partie de mon écran de connexion. J'utilise Shared_Prreferences pour enregistrer la case à cocher Se souvenir de moi et le nom d'utilisateur. La valeur de la case à cocher fonctionne, mais le nom d'utilisateur n'est pas défini. Je sais que c'est sauvegardé parce que je peux voir la valeur à l'aide d'impression. Mais je suppose que cela est d'être mis trop tard, car mon champ de texte est vide. Des idées?
class RmoLogin extends StatefulWidget {
static const String id = 'login_screen';
@override
_RmoLoginState createState() => _RmoLoginState();
}
class _RmoLoginState extends State<RmoLogin> {
final TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
final TextEditingController usernameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
bool showSpinner = false;
bool rememberMe = false;
String userName = '';
_saveRememberUser() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('username', usernameController.text);
prefs.setBool('remember', rememberMe);
}
_getRememberUser() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
userName = prefs.getString('username') ?? '';
rememberMe = prefs.getBool('remember') ?? false;
}
@override
void initState() {
super.initState();
_getRememberUser();
if (rememberMe) {
usernameController.text = userName;
}
}
@override
Widget build(BuildContext context) {
final userField = UserTextField(style: style, usernameController: usernameController);
final passwordField = PasswordTextField(style: style, passwordController: passwordController);
final rememberMeCheckbox = Checkbox(
value: rememberMe,
onChanged: (newValue) {
setState(() {
rememberMe = newValue;
});
},
);
3 Réponses :
Parce que l'instanciation SharedPreferences est asynchrone et la méthode de construction elle-même n'est pas, au moment de la création de l'instance et que la valeur est accessible, la méthode de construction aurait déjà été appelée et vos widgets construits.
Cependant, pour les choses Comme SharedPreferences et bases de données, la meilleure façon de les implémenter est d'utiliser l'approche Singleton, c'est-à-dire une instance que vous pouvez utiliser sur toute l'application. Dans ce cas au lieu de créer une nouvelle instance SharedPreferences chaque fois que l'une ou l'autre méthode est appelée, il sera préférable de créer une seule instance de celui-ci et d'utiliser cette instance pour mettre à jour l'ensemble et obtenir les valeurs. P>
vous pourriez aussi Créez un service pour les préférences SharedPrefereces que vous pouvez utiliser sur l'ensemble de l'application. P> puis dans votre méthode principale, vous pouvez créer une instance de spreferferferences partagée et l'utiliser pour initialiser le service SharedPreferencesService . P> EG. P>
SharedPreferencesService service;
Future<void> main() async {
// flutter will complain if this isn't present
WidgetsFlutterBinding.ensureInitialized();
final prefs = await SharedPreferences.getInstance();
service = SharedPreferencesService(prefs);
runApp(YourApp());
}
Superfo! Pourriez-vous me donner un exemple d'appel des méthodes sur le service? Merci.
@Paulcoshott J'ai créé un gist sur github que vous pouvez consulter gist.github.com/danagbemava/fe08830636771D980DC58A7 < / a>
Juste un bref look .... mais p>
Vous appelez Ma solution serait d'utiliser un _getremembernerUser code> synchrone dans initstate () code> quand il s'agit d'une méthode asynchrone p>
initstate () code> n'est pas le bon endroit pour l'appeler comme initstate () code> est un synchronus @override. p>
fuleBuilder code> dans votre Build () code> méthode et appelez _getRemembertuser code> là. p>
Il vous suffit de mettre à jour l'état de vérifier la solution ci-dessous: codage heureux !! p> p> p>
Il renvoie un
futur code>, vous pouvez utiliserattendre code>. Par ex.Await Prefs.Setstring ('Nom d'utilisateur', Usernamecontroller.text); Code>