仅在热重载后检索数据

Data is retrieved only after hot reloading

我是 Flutter 的新手,我正在尝试从 Firebase 实时数据库中检索数据。但是,只有在执行热重载时才会检索来自 firebase 的数据。我不知道该怎么办...这是代码:

import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'Posts.dart';

class HomePage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
   return HomePageState();
  }

}

class HomePageState extends State<HomePage>{

  List <Posts> postsList = [];

  void initState() {
    super.initState();
    _fetchList();
  }

  _fetchList() async {
    DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");

    postsRef.once().then((DataSnapshot snap){
      // ignore: non_constant_identifier_names
      var KEYS = snap.value.keys;
      var DATA = snap.value;

      for(var individualKey in KEYS){

        Posts posts = Posts(

          DATA[individualKey]["date"],
          DATA[individualKey]["description"],
          DATA[individualKey]["time"],

        );
        postsList.add(posts);
      }
  }      );}


    @override
  Widget build(BuildContext context) {


   return Scaffold(
       appBar: AppBar(
       centerTitle: true,
       title: Text(
       "Home",
   )
    ),

    body: Container(

    child: postsList.length==0? Text("Nothing available!") : ListView.builder(
    itemCount: postsList.length,
    itemBuilder:(context,int index){
    return postsUI(postsList[index].description, postsList[index].date, postsList[index].time);
    }
    ),

    ));

  }

  Widget postsUI ( String description, String date, String time){

    return Card(
      elevation: 20.0,

      margin: EdgeInsets.only(left: 25.0 , right:25.0, top:15.0, bottom:15.0),

      child: Container(
        padding: EdgeInsets.all(20.0),

        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children:<Widget> [

            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[

                Text(
                  date,
                  style: Theme.of(context).textTheme.subtitle1,
                  textAlign: TextAlign.center,
                ),

                Text(
                  time,
                  style: Theme.of(context).textTheme.subtitle1,
                  textAlign: TextAlign.center,
                ),

              ],

            ),

            SizedBox(height: 15.0,),
            Text(
              description,
              style: Theme.of(context).textTheme.subtitle2,
              textAlign: TextAlign.center,
            ),


          ],
        ),
      ),

    );

  }


}

PS :仅在执行热重载时从数据库中检索值。

我假设您要检索的数据来自 _fetchList() 调用?它只在热重载中工作的原因是因为你只有 _fetchListinitState 调用——它只在 运行.

上调用

如果您希望获得 real-time 更新(当数据库中的内容发生变化时您的小部件会更新),您需要考虑使用 Streams and StreamBuilder.

如果您希望使用 fetchData Firestore 数据构建 UI 而无需 real-time 更新,Futures and FutureBuilder 就是您想要的。从您的代码来看,我认为这将满足您的需求。

除了 J.Saw 的出色回答,您还可以选择将 postsList 存储在小部件的状态中。

为此,您在数据加载后调用 setState()

  _fetchList() async {
    DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");

    postsRef.once().then((DataSnapshot snap){
      // ignore: non_constant_identifier_names
      var KEYS = snap.value.keys;
      var DATA = snap.value;

      for(var individualKey in KEYS){
        Posts posts = Posts(
          DATA[individualKey]["date"],
          DATA[individualKey]["description"],
          DATA[individualKey]["time"],
        );
        postsList.add(posts);
      }
      setState((){
        this.postsList = postsList;
      });
      
    });
  }

调用 setState() 会导致 Flutter 重新绘制小部件,然后它可以像您已经在做的那样访问数据。


您也许可以不带任何参数地简单地调用 setState(() {}),但我总是更喜欢传入修改后的状态 - 即使不需要它。