我试图像这样从SharedPreferences设置一个字段值:
FutureBuilder<String>(
future: _getUsername(),
initialData: 'Bruh',
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
print(snapshot);
print(snapshot.data);
print(snapshot.hasData);
return snapshot.hasData ? TextFormField(initialValue: snapshot.data, onChanged: _setUsername) : TextFormField();
}
),
这是我正在使用的_getUsername():
Future<String> _getUsername() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('username') ?? 'hmm';
return "Fine";
}
这是控制台输出:
Reloaded 0 of 567 libraries in 352ms.
I/flutter (28961): AsyncSnapshot<String>(ConnectionState.done, tesy, null)
I/flutter (28961): tesy
I/flutter (28961): true
如您所见,输出的L2显示“ tesy”,这是SharedPreferences中的值,但是我只在文本字段中看到“ Bruh”(初始值)。
在我可以找到的所有示例中,在将“ tesy”显示在输入框中之前,将“短暂地”显示“ Bruh”(如果有的话)。我要去哪里错了?
答案 0 :(得分:1)
我想问题出在TextFormField
本身。重建组件时,不会考虑已更改的initialValue
。如果您想要一个“动态”初始值,最好提供一个明确的控制器。像这样:
class TestApp extends StatefulWidget {
@override
_TestAppState createState() => _TestAppState();
}
class _TestAppState extends State<TestApp> {
final TextEditingController _controller = TextEditingController();
@override
void initState() {
super.initState();
_controller.text = 'Initial';
_initUsername();
}
Future<void> _initUsername() async {
final username = await _getUsername();
_controller.value = _controller.value.copyWith(text: username);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: TextFormField(controller: _controller, onChanged: (_) {}),
),
);
}
Future<String> _getUsername() async {
await Future.delayed(Duration(seconds: 1));
return 'Loaded';
}
}
答案 1 :(得分:1)
尝试更改
TextFormField(initialValue: snapshot.data, onChanged: _setUsername)
收件人
TextFormField(key: UniqueKey(), initialValue: snapshot.data, onChanged: _setUsername)
这是因为TextFormField为“有状态”,并且小部件树未检测到更改,因此没有放置唯一键,无法完成所需的工作,另一个选择是使用TextEditingrController更新值。