Flutter initState () не получает данные немедленно, для их просмотра необходимо выполнить горячую перезагрузку - PullRequest
0 голосов
/ 05 февраля 2020
class _SelectMedChallengeState extends State<SelectMedChallenge> {

List<String> categoryList;
@override
void initState() {
  super.initState();
  setState(() {
    categoryList = DatabaseService().getCategoryList();
  });
  print(categoryList);
}

createAlertDialog(BuildContext context){
return showDialog(context: context, builder: (context){
  return AlertDialog(
    content: Center (
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text(
            'CATEGORY',
            style: TextStyle(
              fontFamily: 'MuseoSans',
              fontSize: 24.0,
            ),
          ),
          SizedBox(height: 20.0,),
          ButtonTheme (
            minWidth: 288.0,
            height: 109.0,
            buttonColor: Color.fromARGB(255, 102, 199, 227),
            child: RaisedButton (
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10.0),
                side: BorderSide(
                  color: Colors.transparent,
                ),
              ),
              child: Text(
                'BEGINNER',
                style: TextStyle(
                  color: Color.fromARGB(255, 76, 62, 62),
                  fontSize: 22.0,
                  fontFamily: 'MuseoSans',
                ),
              ),
              onPressed: () {
                Navigator.pop(context);
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MedChallenge()),
                );
              },
            ),
          ),
          SizedBox(height: 10.0),
          ButtonTheme (
            minWidth: 288.0,
            height: 109.0,
            buttonColor: Color.fromRGBO(248, 227, 160, 1.0),
            child: RaisedButton (
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10.0),
                side: BorderSide(
                  color: Colors.transparent,
                ),
              ),
              child: Text(
                'INTERMEDIATE',
                style: TextStyle(
                  color: Color.fromARGB(255, 76, 62, 62),
                  fontSize: 22.0,
                  fontFamily: 'MuseoSans',
                ),
              ),
              onPressed: () {
                Navigator.pop(context);
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MedChallenge()),
                );
              },
            ),
          ),
          SizedBox(height: 10.0),
          ButtonTheme (
            minWidth: 288.0,
            height: 109.0,
            buttonColor: Color.fromRGBO(234, 135, 137, 1.0),
            child: RaisedButton (
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10.0),
                side: BorderSide(
                  color: Colors.transparent,
                ),
              ),
              child: Text(
                'ADVANCED',
                style: TextStyle(
                  color: Color.fromARGB(255, 76, 62, 62),
                  fontSize: 22.0,
                  fontFamily: 'MuseoSans',
                ),
              ),
              onPressed: () {
                Navigator.pop(context);
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MedChallenge()),
                );
              },
            ),
          ),
        ],
      ),
    ),
  );
});
}


@override
Widget build(BuildContext context) {
return Scaffold(
    appBar: AppBar(
      backgroundColor: Color.fromRGBO(248, 227, 160, 1.0),
      iconTheme: IconThemeData(
        color: Color.fromRGBO(77, 72, 91, 1.0), //#4D485B
      ),
      title: Text(
        'CATEGORIES',
        style: TextStyle(
          color: Color.fromRGBO(77, 72, 91, 1.0), //#4D485B
          fontFamily: 'MuseoSans',
          fontWeight: FontWeight.bold,
        ),

      ),
      centerTitle: true,

      actions: <Widget>[],

    ),

    body: Center(
      child: ListView.separated(
        separatorBuilder: (context, index) => Divider(
          color: Colors.lightBlue,
          thickness: 2.0,
        ),
        itemCount: categoryList.length,
        itemBuilder: (BuildContext context, int index) {
          return GestureDetector(
            onTap: () {
              createAlertDialog(context);
            },
            child: Container(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Center(
                  child: Text(
                    '${categoryList[index]}',
                    style: TextStyle(
                      fontFamily: 'MuseoSans',
                      fontSize: 25.0,
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      ),
    ),

 );
}
}

В моем iniitState () я пытаюсь инициализировать свой categoryList для данных, которые я запрашиваю из облачного пожарного хранилища, вызывая DatabaseService (). GetCategoryList () - функцию, которую я написал для запроса база данных. Затем я пытаюсь использовать categoryList в теле моего скаффолда в ListView. Когда я go на этот экран в моем приложении, тело пусто, и в консоли он печатает пустой список. Единственный раз, когда данные на самом деле отображаются, это если я делаю горячую перезагрузку, когда я на экране категории. Я попытался выполнить горячий перезапуск и снова запустить приложение, и тело все еще пусто, пока я не выполню горячую перезагрузку после перехода к этому экрану в моем приложении. Любая помощь будет оценена.

1 Ответ

5 голосов
/ 05 февраля 2020

Если DatabaseService().getCategoryList() - это Future или Stream, то вы не ждете ответа, вы пытаетесь получить его немедленно через свой initState.

Переместите ваш метод внутри функции, используя async ключевое слово или просто добавьте:

.then((result) => // your login) в конце вашего будущего.

Как только вы уверены, что получаете результат для своего асинхронного вызова, вы можете позвонить setState обновить список и отобразить результаты.

Пример:

@override
void initState() {
  _fetchList();
}

_fetchList() async {
  DatabaseService().getCategoryList().then((result) {
    setState(() => categoryList = result);
  });
}

Другие варианты использования для извлечения списка могут быть:

setState(() {
    categoryList.addAll(result);
});
// Another one
for (var item in items) {
  setState(() {
    categoryList.add(item);
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...