【问题标题】:Flutter initState() not retrieving data immediately, need to do hot reload to view itFlutter initState() 不立即检索数据,需要进行热重载才能查看
【发布时间】:2020-02-05 20:18:44
【问题描述】:
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,
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      ),
    ),

 );
}
}

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

【问题讨论】:

    标签: firebase flutter dart google-cloud-firestore


    【解决方案1】:

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

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

    .then((result) =&gt; // 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);
      });
    }
    

    【讨论】:

    • 这就是我的 getCategoryList() 函数的样子,我需要让它异步吗?如果我这样做了,那么我怎么能在 initState() 中调用它,因为我不能使 initState() 异步List&lt;String&gt; getCategoryList() { List&lt;String&gt; categoryList =[]; categoryCollection.getDocuments().then((QuerySnapshot catDocs) { for(int i = 0; i &lt; catDocs.documents.length; i++) { categoryList.add(catDocs.documents[i].data['category']); } }); return categoryList; }
    • 在我的回答中建议的函数中添加 DatabaseService().getCategoryList() 方法。让我更新一下,给你看一个例子。
    • 立即查看我的示例
    • 当我尝试添加 .then((result) => 时出现“未为类 List 定义 then”的错误
    • 那么你的 getCategoryList() 方法应该返回 Future。
    猜你喜欢
    • 2020-10-13
    • 2019-03-06
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 2010-11-28
    相关资源
    最近更新 更多