I was making a settings page for my flutter app to save a single number. I used shared_preferences. It can save the value into saved_preferences, and it can retrieve the data, but when settings page is loaded again it doesn't load the data into the widget. Here are some pictures to show what is happening.
I believe it has something to do with the async, because the widgets are already loading without it first getting the data from shared_preferences. But I don't know why the setState() wouldn't handle that after the data has loaded.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Settings extends StatefulWidget {
const Settings({Key? key}) : super(key: key);
@override
State<Settings> createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
late SharedPreferences preferences;
int? max;
_loadMax() async {
preferences = await SharedPreferences.getInstance();
if (!preferences.containsKey('max')) {
_setMax(16);
} else {
max = preferences.getInt('max');
setState(() {});
}
}
_setMax(int value) async {
await preferences.setInt('max', value);
max = value;
setState(() {});
}
@override
Widget build(BuildContext context) {
if (max == null) _loadMax();
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Max Number (Inclusive) ',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(width: 10.0),
SizedBox(
width: 100,
height: 50,
child: TextFormField(
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Maximum',
counterText: '',
),
initialValue: max.toString(),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r"[0-9.]")),
],
onFieldSubmitted: (s) {
_setMax(int.parse(s));
},
maxLength: 4,
keyboardType: TextInputType.number,
),
),
],
),
ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('Home'),
),
]),
);
}
}
CodePudding user response:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Settings extends StatefulWidget {
const Settings({Key? key}) : super(key: key);
@override
State<Settings> createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
late SharedPreferences preferences;
int? max;
TextEditingController textFeildData = TextEditingController();
_loadMax() async {
preferences = await SharedPreferences.getInstance();
if (!preferences.containsKey('max')) {
_setMax(16);
} else {
textFeildData.text = preferences.getInt('max').toString();
print(textFeildData);
setState(() {});
}
}
_setMax(int value) async {
await preferences.setInt('max', value);
max = value;
setState(() {});
}
@override
Widget build(BuildContext context) {
// if (max == null) _loadMax();
return Scaffold(
body: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Max Number (Inclusive) ',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(width: 10.0),
SizedBox(
width: 100,
height: 50,
child: TextFormField(
controller: textFeildData,
decoration: const InputDecoration(
border: OutlineInputBorder(),
// labelText: 'Maximum',
),
// initialValue: max.toString(),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r"[0-9.]")),
],
onFieldSubmitted: (s) {
_setMax(int.parse(s));
},
maxLength: 4,
keyboardType: TextInputType.number,
),
),
],
),
ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('Home'),
),
]),
);
}
}
hopefully this will help just give textfield a controller and do what ever you want with the field text