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 更新值。