Flutter Gridview不更新Firebase中的值

时间:2018-11-24 10:02:56

标签: android ios dart flutter flutter-layout

我是新手。我正在使用Firebase构建应用程序。在我的应用中,我想在gridview中显示产品详细信息。详细信息取自firebase。我正在成功获得价值。但是我从不更新到GridView列表的firebase获得的值。我的代码如下所示。

AppMain.Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:augr/location/LocationScreen.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  MyApp({this.firestore});
  final Firestore firestore;


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(title: 'My Shop', firestore: firestore)
    );
  }
}

class MyHomePage extends StatefulWidget {

  MyHomePage({Key key, this.title, this.firestore}) : super(key: key);
  final Firestore firestore;
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState(firestore: firestore);
}

class _MyHomePageState extends State<MyHomePage> {
  _MyHomePageState({this.firestore});
  final Firestore firestore;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
        iconTheme: IconThemeData(
        color: Colors.black, //change font color here
    ),
    backgroundColor: new Color(0xFFFAFAFA),
        )
            title:"title",
      body: TheGridview().build(),
    );
  }
  }

class TheGridview{
  Card makeGridCell(String name, IconData icon){
    return Card(
      elevation: 1.0,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          mainAxisSize: MainAxisSize.min,
          verticalDirection: VerticalDirection.down,
          children: <Widget>[
            Center(child: Icon(icon)),
            Text(name)
          ],
        ),
    );
  }

  GridView build(){
    return GridView.count(
      primary: true,
      padding: EdgeInsets.all(1.0),
      crossAxisCount: 2,
      childAspectRatio: 1.0,
      mainAxisSpacing: 1.0,
      crossAxisSpacing: 1.0,

      children: createChildrenTexts(),

    /*  children: <Widget>[
        makeGridCell("Home", Icons.access_alarm)
      ],*/


    );
  }

  List<Widget> createChildrenTexts(){
    List<Widget> childrenTexts = List<Widget>();


    getProduceID().then((data){
      for(int i=0;i<data.length;i++){

         childrenTexts.add(makeGridCell(data[i].data['message'], Icons.access_alarm));
        print("data from firebase:"+data[i].data['message']);

      }
    });

    return childrenTexts;
  }

  Future<List<DocumentSnapshot>> getProduceID() async{
    QuerySnapshot querySnapshot = await Firestore.instance.collection("messages").getDocuments();
    var list = querySnapshot.documents;
    return list;
  }
}

createChildrenTexts是我要在GridView中添加项目的方法。 from firebase正在控制台中打印。但不添加列表。我知道我想用有状态的小部件编写。但是我该怎么写,请帮帮我。

2 个答案:

答案 0 :(得分:0)

问题是您正在尝试从Firebase提取数据以进行构建方法调用。请记住,在反应式编程方法中,您将网络工作与构建方法分开进行,并将从网络调用返回的数据置于状态。在每次状态更改时,框架都会重新绘制框架。

下面的代码可能会对您有所帮助,但我强烈建议您仔细阅读this

  1. 在状态类中声明文档变量

    var documents = [];

  2. 从initState函数调用firestore并使用setState()函数更新文档值

    void initState() { super.initState(); Firestore.instance.collection("messages").getDocuments().then((data){ var list = data.documents; setState((){ documents = list; }); }); }

  3. 使用documents变量来循环并呈现数据

    List<Widget> createChildrenTexts(){
      List<Widget> childrenTexts = List<Widget>();
      for(int i=0;i<documents.length;i++){ 
        childrenTexts.add(makeGridCell(documents[i].data['message'], Icons.access_alarm));
        print("data from firebase:"+documents[i].data['message']);  
      }
      return childrenTexts;
    }
    

答案 1 :(得分:0)

createChildrenTexts类中添加_MyHomePageState时,我得到了答案。因此,我可以从Firestore中访问数据。然后在documents中声明数组_MyHomePageState。然后还添加了一个标志isDocLoaded,以检查是否存储了该值。我的最终代码如下所示。

  import 'dart:async';
  import 'package:flutter/material.dart';
  import 'package:augr/location/LocationScreen.dart';
  import 'package:cloud_firestore/cloud_firestore.dart';

  void main() => runApp(MyApp());

  class MyApp extends StatelessWidget {
    // This widget is the root of your application.

    MyApp({this.firestore});
    final Firestore firestore;


    @override
    Widget build(BuildContext context) {
      return MaterialApp(
          home: MyHomePage(title: 'My Shop', firestore: firestore)
      );
    }
  }

  class MyHomePage extends StatefulWidget {

    MyHomePage({Key key, this.title, this.firestore}) : super(key: key);
    final Firestore firestore;
    final String title;

    @override
    _MyHomePageState createState() => new _MyHomePageState(firestore: firestore);
  }

  class _MyHomePageState extends State<MyHomePage> {
    _MyHomePageState({this.firestore});
    final Firestore firestore;

    var documents = [];
    bool isDocLoaded=false;


    void initState() {
      Firestore.instance.collection("messages").getDocuments().then((data) async {
        var list = data.documents;
        documents = list;
        print("init state document:" +
            documents.length.toString()); // value is getting
        super.initState();
        setState(() {
          isDocLoaded = true;
          documents = list;
        });
      });
    }

    @override
    Widget build(BuildContext context) {
      return new Scaffold(
        appBar: new AppBar(
          iconTheme: IconThemeData(
            color: Colors.black, //change font color here
          ),
          backgroundColor: new Color(0xFFFAFAFA),
        )
        title:"title",
        body: isDocLoaded? TheGridview():Center(child:CircularProgressIndicator()),
      );
    }

    Widget TheGridView(){
      return GridView.count(
        primary: true,
        padding: EdgeInsets.all(1.0),
        crossAxisCount: 2,
        childAspectRatio: 1.0,
        mainAxisSpacing: 1.0,
        crossAxisSpacing: 1.0,

        children: createChildrenTexts(),

        /*  children: <Widget>[
              makeGridCell("Home", Icons.access_alarm)
            ],*/
      );
    }

    Card makeGridCell(String name, IconData icon){
      return Card(
        elevation: 1.0,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          mainAxisSize: MainAxisSize.min,
          verticalDirection: VerticalDirection.down,
          children: <Widget>[
            Center(child: Icon(icon)),
            Text(name)
          ],
        ),
      );
    }
    List<Widget> createChildrenTexts(){
      print("createChildrenTexts:"+documents.length.toString()); // the value getting 0
      List<Widget> childrenTexts = List<Widget>();
      for(int i=0;i<documents.length;i++){
        childrenTexts.add(makeGridCell(makeGridCell(data[i].data['message'], Icons.access_alarm));
        }
            return createchildwidget;
        }
  }