Flutter initState() 不立即检索数据,需要进行热重载才能查看

Sal*_*ine 0 dart firebase flutter google-cloud-firestore

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,
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      ),
    ),

 );
}
}
Run Code Online (Sandbox Code Playgroud)

在我的 initState() 中,我试图通过调用 DatabaseService().getCategoryList() 来将我的 categoryList 初始化为我从云 Firestore 查询的数据,这是我编写的用于查询数据库的函数。然后我尝试在 ListView 的脚手架主体中使用 categoryList。当我在我的应用程序中转到该屏幕时,主体是空的,并且在控制台中它会打印一个空列表。数据实际显示的唯一时间是当我在类别屏幕中时是否进行热重载。我尝试进行热重启并再次运行该应用程序,并且在我导航到我的应用程序中的该屏幕后进行热重新加载之前,主体仍然是空的。任何帮助,将不胜感激。

Mar*_*lla 7

如果DatabaseService().getCategoryList()是 Future 或 Stream,那么您不是在等待响应,而是在尝试通过 initState 立即获取它。

使用async关键字将您的方法移动到函数内或简单地添加:

.then((result) => // your login) 在你的未来结束时。

一旦确定获得了异步调用的结果,就可以调用setState更新列表并显示结果。

例子:

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

_fetchList() async {
  DatabaseService().getCategoryList().then((result) {
    setState(() => categoryList = result);
  });
}
Run Code Online (Sandbox Code Playgroud)

其他用于获取列表的可能是:

setState(() {
    categoryList.addAll(result);
});
// Another one
for (var item in items) {
  setState(() {
    categoryList.add(item);
  });
}
Run Code Online (Sandbox Code Playgroud)