Flutter / Dart не будет отображать снимок FutureBuilder при разрешении - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь установить значение поля из 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» будет отображаться в поле ввода. Куда я иду не так?

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Попробуйте изменить

TextFormField(initialValue: snapshot.data, onChanged: _setUsername)

На

TextFormField(key: UniqueKey(), initialValue: snapshot.data, onChanged: _setUsername)

Это потому, что TextFormField имеет «Stateful» и дерево виджетов не обнаруживает изменения, помещая уникальный ключ, делает задание, которое вы хотите, другой вариант - обновить значение с помощью TextEditingrController.

1 голос
/ 17 февраля 2020

Я думаю, проблема в самом TextFormField. Когда компонент перестраивается, измененное значение initialValue не учитывается. Если вы хотите иметь начальное значение «dynamici c», лучше предоставить явный контроллер. Как то так:

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';
  }
}
...