1
votes

I am new to flutter. Following is my code for getting data from a firestore collection called posts.The problem when the first times app loaded it takes few seconds to load data until that it show a blank screen.It only happens only the first time.So how to display loading spinner or something to user until data gets loaded? (Not that this is not the whole code)

class ForumHome extends StatefulWidget {
  @override
  _ForumHomeState createState() => _ForumHomeState();
}

dbMethods dbcrud = new dbMethods();

class _ForumHomeState extends State<ForumHome> {
  String title, content;
  //Subscribing for post details
  StreamSubscription<QuerySnapshot> subscription;
  List<DocumentSnapshot> snapshot;
  CollectionReference collectionReference =
      Firestore.instance.collection("posts");

  @override
  void initState() {
    super.initState();
    subscription = collectionReference.snapshots().listen((datasnapshot) {
      setState(() {
        snapshot = datasnapshot.documents;
      });
    });
  }

  @override
  Widget build(BuildContext context) {

    int num = snapshot?.length ?? 0;
    return Scaffold(
      appBar: AppBar(title: Text('Idea Forum '), backgroundColor: Colors.pink),
      body: new ListView.builder(
        itemCount: num,
        itemBuilder: (context, index) {
          return new Card(
            elevation: 15.0,
            margin: EdgeInsets.all(10.0),
            child: new ListTile(
                onTap: () {
                  //For udating the view count
                  snapshot[index]
                      .reference
                      .updateData({'Views': snapshot[index].data['Views'] + 1});

4

4 Answers

2
votes

I suggest creating a controller for circularProgress, as in the example:

class _testProgressState extends State<testProgress> {

bool _progressController = true;


@override
void initState() {
  super.initState();

  subscription = collectionReference.snapshots().listen((datasnapshot) {
    setState(() {
      snapshot = datasnapshot.documents;
      _progressController = false;
    });
  });

}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: _progressController
        ? CircularProgressIndicator()
        : ListView.builder(
            itemCount: 3,
            itemBuilder: (context, index) {
              return Card();
            }),
  );
}
}

So whenever you find it necessary to call some function to collect data, just setState setting _controllerProgress to true, and when the data arrives returns it to false!

0
votes

You need to evaluate state of the connection.

body: new ListView.builder(
        itemCount: num,
        itemBuilder: (context, index) {
          if (snapshot.connectionState == ConnectionState.waiting)
          return CircularProgressIndicator();
          return new Card(
            elevation: 15.0,
            margin: EdgeInsets.all(10.0),
            child: new ListTile(
                onTap: () {
                  //For udating the view count
                  snapshot[index]
                      .reference
                      .updateData({'Views': snapshot[index].data['Views'] + 1});
0
votes

You need to create a future widget,

 FutureBuilder(
        future: YOUR_ASYNC_TASK_HERE,
        builder: (context, AsyncSnapshot<YOUR_RETURN_TYPE_FROM_ASYNC> snapshot) {
          return (snapshot.connectionState == ConnectionState.done)?HomePage():_buildWaitingScreen();
        },
      ),

For the _buildWaitingScreen you can use

Widget _buildWaitingScreen() {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        child: CircularProgressIndicator(),
      ),
    );
  }
0
votes

you can check if snapshot has data and while its loading show a loader.also i have extacted your listview to a separate widget

Widget _numcard(){
     if (snapshot != null) {
       ListView.builder(
            itemCount: num,
            itemBuilder: (context, index) {
              return new Card(
                elevation: 15.0,
                margin: EdgeInsets.all(10.0),
                child: new ListTile(
                    onTap: () {
                      //For udating the view count
                      snapshot[index]
                          .reference
                          .updateData({'Views': snapshot[index].data['Views'] + 1});
                    })});
          }else {return Container(
            child:CircularProgressIndicator());}}