Flutter/Dart 解析后不会显示 FutureBuilder 快照
Flutter/Dart won't display FutureBuilder snapshot when resolved
我正在尝试从 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'。
在我能找到的所有示例中,'Bruh' 会(非常)短暂地(如果有的话)显示,然后 'tesy' 会显示在输入框中。我哪里错了?
我想问题出在 TextFormField
本身。重建组件时,不考虑更改的 initialValue
。如果你想有一个 "dynamic" 初始值,最好提供一个显式控制器。像这样:
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';
}
}
尝试改变
TextFormField(initialValue: snapshot.data, onChanged: _setUsername)
至
TextFormField(key: UniqueKey(), initialValue: snapshot.data, onChanged: _setUsername)
这是因为 TextFormField 是 "Stateful" 并且小部件树未检测到更改,放置唯一键,完成您想要的工作,另一个选项是使用 TextEditingrController 更新值。
我正在尝试从 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'。
在我能找到的所有示例中,'Bruh' 会(非常)短暂地(如果有的话)显示,然后 'tesy' 会显示在输入框中。我哪里错了?
我想问题出在 TextFormField
本身。重建组件时,不考虑更改的 initialValue
。如果你想有一个 "dynamic" 初始值,最好提供一个显式控制器。像这样:
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';
}
}
尝试改变
TextFormField(initialValue: snapshot.data, onChanged: _setUsername)
至
TextFormField(key: UniqueKey(), initialValue: snapshot.data, onChanged: _setUsername)
这是因为 TextFormField 是 "Stateful" 并且小部件树未检测到更改,放置唯一键,完成您想要的工作,另一个选项是使用 TextEditingrController 更新值。