解决后,Flutter / Dart将不会显示FutureBuilder快照

时间:2020-02-17 20:25:28

标签: flutter dart future

我试图像这样从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”(如果有的话)。我要去哪里错了?

2 个答案:

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