【问题标题】:flutter initstate() list is not accessing another class widget颤振 initstate() 列表未访问另一个类小部件
【发布时间】:2018-11-25 19:16:07
【问题描述】:

我正在用颤振创建一个应用程序。我想从 firebase 获取数据并显示网格视图。数据正在从 firebase 正确获取。在initState() 中获取数据但它没有更新另一个类TheGridview 扩展自_MyHomePageState。我正在使用一个变量 documents 用于存储来自 firebase 的列表。 initState() 文档值,但在方法 createchildwidget 中文档变为空。我尝试了很多方法,请帮助我。代码如下所示。

    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 = [];

      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((){
            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: TheGridview().build(),
        );
      }
    }

    class TheGridview extends _MyHomePageState{
      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)
            ],
          ),
        );
      }

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

          children: createchildwidget(),

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


        );
      }

      List<Widget> createchildwidget(){
        print("createchildwidget:"+documents.length.toString()); // the value getting 0
        List<Widget> createchildwidget = List<Widget>();
        for(int i=0;i<documents.length;i++){
          createchildwidget.add(TheGridview().makeGridCell(makeGridCell(data[i].data['message'], Icons.access_alarm));

        }
        return createchildwidget;
      }


    }

【问题讨论】:

    标签: android ios dart flutter


    【解决方案1】:

    不要将TheGridView 作为一个新类,而是将其作为一个函数并在document 数据加载时调用它。 试试这个:

        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 _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: createchildwidget(),
    
              /*  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> createchildwidget(){
            print("createchildwidget:"+documents.length.toString()); // the value getting 0
            List<Widget> createchildwidget = List<Widget>();
            for(int i=0;i<documents.length;i++){
              createchildwidget.add(makeGridCell(makeGridCell(data[i].data['message'], Icons.access_alarm));
            }
    return createchildwidget;
          }
        }
    

    【讨论】:

    • 谢谢你的回答是正确的。非常感谢。
    • 扩展小部件的状态类不是一个好主意。相反,使用函数或创建一个新的小部件。
    【解决方案2】:

    在加载数据时尝试使用另一个小部件:

            @override
              Widget build(BuildContext context) {
                return documents.isEmpty? Center(child: CircularProgressIndicator()) : GridView.count(
                  primary: true,
                  padding: EdgeInsets.all(1.0),
                  crossAxisCount: 2,
                  childAspectRatio: 1.0,
                  mainAxisSpacing: 1.0,
                  crossAxisSpacing: 1.0,
                  children:  : createchildwidget(),
    
                  /*  children: <Widget>[
                    makeGridCell("Home", Icons.access_alarm)
                  ],*/
    
                );
              }
    

    【讨论】:

    • 显示错误“容器类型不是 List 类型的子类型”
    • 对不起,我修正了答案
    • 添加上述代码时。没有进入“createchildwidget()”,进度条显示不停。
    • 有什么解决办法吗?
    • 使用FutureBuilder,这里更干净、更好。 docs.flutter.io/flutter/widgets/FutureBuilder-class.htmlFirestore.instance.collection("messages").getDocuments() - 返回未来
    猜你喜欢
    • 2020-06-05
    • 2021-10-23
    • 2020-01-10
    • 1970-01-01
    • 2020-10-08
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    相关资源
    最近更新 更多