我一直在尝试在Widget启动时读取首选项,但一直无法找到解决方案。 我希望在TextField中显示用户名(他们可以更改)并将其存储在首选项中,以便在它们返回页面时立即显示。
class _MyHomePageState extends State<MyHomePage> {
TextEditingController _controller;
:
:
Future<Null> storeName(String name) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("name", name);
}
@override
initState() async {
super.initState();
SharedPreferences prefs = await SharedPreferences.getInstance();
_controller = new TextEditingController(text: prefs.getString("name"));
}
@override
Widget build(BuildContext context) {
:
:
return new TextField(
decoration: new InputDecoration(
hintText: "Name (optional)",
),
onChanged: (String str) {
setState(() {
_name = str;
storeName(str);
});
},
controller: _controller,
)
}
}
我有了在initState()上使用async的想法:
flutter timing problems on stateful widget after API call
但async似乎在启动时导致此错误:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 967 pos 12:
'_debugLifecycleState == _StateLifecycle.created': is not true.
我查找了FutureBuilder的示例,但似乎找不到任何类似于我想要做的事情。
答案 0 :(得分:15)
我建议不要在initState()上使用async。但是你可以通过将SharedPreferences包装在另一个函数中并将其声明为异步来以不同的方式执行此操作。
我修改了你的代码。请检查一下是否有效。非常感谢。
修改后的代码:
class _MyHomePageState extends State<MyHomePage> {
TextEditingController _controller;
String _name;
Future<Null> getSharedPrefs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
_name = prefs.getString("name");
setState(() {
_controller = new TextEditingController(text: _name);
});
}
@override
void initState() {
super.initState();
_name = "";
getSharedPrefs();
}
@override
Widget build(BuildContext context) {
return new TextField(
decoration: new InputDecoration(
hintText: "Name (optional)",
),
onChanged: (String str) {
setState(() {
_name = str;
storeName(str);
});
},
controller: _controller,
);
}
}
如果这有帮助,请告诉我。 谢谢。
答案 1 :(得分:1)
initState()
是一个同步函数,您无法标记async
,因为async
将该函数转换为异步函数。
以下代码有助于在加载时加载共享的首选项值,并用于更新小部件。
@override
void initState() {
super.initState();
SharedPreferences.getInstance().then((prefValue) => {
setState(() {
_name = prefValue.getString('name')?? "";
_controller = new TextEditingController(text: _name);
})
});
}
答案 2 :(得分:1)
在应用级别进行。
SharedPreferences prefs;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
prefs = await SharedPreferences.getInstance();
// Rest of your code...
}
答案 3 :(得分:0)
还有没有比设置新状态更好的方法了?
我正在构建一个可以在亮和暗模式之间切换的应用,并且该应用在获取用户偏好设置时闪烁...
void _loadOptions() async {
_options = AppOptions(
theme: kLightAppTheme,
textScale: kAllTextScaleValues[0],
platform: defaultTargetPlatform,
);
await _storage.fetchOptions().then((result) {
if (result != null) {
setState((){
_options = result;
});
}
}
);
}
@override
void initState() {
super.initState();
_generateAPIs();
_loadOptions();
print(_options.toString());
}