(FLUTTER)ontap ListView(return listTile())with Streambuilder导致继承的数据为空?

rjee0c15  于 2023-04-13  发布在  Flutter
关注(0)|答案(1)|浏览(97)

嗨,我试图创建一个简单的实时数据库使用Streambuilder,同时返回一个Listview.builder,其中是一个ListTile。我希望给予ListTile一个移动到其他dart的能力。哪一个,我设法做到了,但是当我试图传递项目时,它变成null,但当我试图打印它时,它在终端打印。

class ListItemsDisplay extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _ListItemsDisplay();
      }
    }

    class _ListItemsDisplay extends State<ListItemsDisplay> {
      @override
      Widget build(BuildContext context) {
        return new StreamBuilder(
            stream: Firestore.instance.collection("posts").snapshots(),
            builder: (context, snapshot) {
              if (!snapshot.hasData) {
                return Center(
                  child: Text("Loading.."),
                );
              } else {
                return ListView.builder(
                    itemCount: snapshot.data.documents.length,
                    itemBuilder: (context, index)`enter code here` {
                      if (snapshot.data.documents[index]['title'] != null &&
                          snapshot.data.documents[index]['title'] != "" &&
                          snapshot.data.documents[index]['title'] != " ") {
                        print(
                            "MY ID: " + snapshot.data.documents[index].documentID);
                        return ListTile(
                            title: Text(snapshot.data.documents[index]['title']),
                            onTap: () {
                              if (snapshot.data.documents[index]['title'] != 

    null) {**//AS YOU CAN SEE HERE IM TRYING TO PASS the document id in DISPLAYITEM() CLASS**
    print("MY ITEM ID ""TAPPED"" IF NOT NULL: "+snapshot.data.documents[index].documentID);
                                Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                        builder: (context) => DisplayItem(snapshot.data.documents[index].documentID)));
                              } else {
                                print("MY ITEM ID ""TAPPED"" IF NULL: "+snapshot.data.documents[index].documentID);
                              }
                            });
                      } else {
                        return ListTile(
                          title: Text("Missing title [REPORT TO ADMIN]"),
                        );
                      }
                    });
              }
            });
      }
    }

这是我的DisplayItem类。

class DisplayItem extends StatelessWidget {
  final String _myId;
  DisplayItem(this._myId);
  String getTitle(String myId) {
    if(myId.isNotEmpty && myId!=null) {
      Firestore.instance.collection("posts").document(myId).get().then((value) {
        if (value.data['title'].toString() != null &&
            value.data['title'].toString() != "" &&
            value.data['title'].toString() != " ")
          return value.data['title'].toString();
        else
          return "NONE FOUND";
      });
    }
    else
      return "HELLO";
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
        appBar: AppBar(
        title: Text("TITLE"),
    ),
    body: Column(
    children: <Widget>[
      Text(getTitle(_myId)),
    ],
    ),
    ),
    );
    }
  }

即时通讯试图建立一个实时数据库(firestore),其中Flutter将显示列表中的项目,点击后列出的任何项目;它将把用户重定向到另一个DART文件,在该文件中,该DART文件将显示该项目的更多描述。
下面是错误:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building DisplayItem(dirty):
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 298 pos 10: 'data != null'

The relevant error-causing widget was: 
  DisplayItem file:///D:/Programming/Flutter_Projects/flutter_study/lib/main.dart:64:59
When the exception was thrown, this was the stack: 
#2      new Text (package:flutter/src/widgets/text.dart:298:10)
#3      DisplayItem.build (package:flutterstudy/Display.dart:31:7)
#4      StatelessElement.build (package:flutter/src/widgets/framework.dart:4576:28)
#5      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4502:15)
#6      Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
...
════════════════════════════════════════════════════════════════════════════════════════════════════

HERE IS THE ID IM TRYING TO PASS
I/flutter (11339): MY NOT NULL ID: sc94LjZJz57t947YgTlp

当我单击此选项时(DisplayItem文件:///D:/Programming/Flutter_Projects/flutter_study/lib/main. dart:64:59)
IM重定向到这里:builder:(context)=〉DisplayItem(snapshot.data.documents[index].documentID)));

HERE's WHAT HAPPENS:
as soon as I ran, I added a print method that will print document ID of items.
I/flutter (13386): MY ID: sc94LjZJz57t947YgTlp
I/flutter (13386): MY ID: xqbkvhVveYhr3YvgSGuE

Now I clicked any of the Item

IT Shows the **ERROR ON TERMINAL** then it displays the last method I added in onTap, which print method:
I/flutter (13386): MY ITEM ID TAPPED IF NOT NULL: sc94LjZJz57t947YgTlp
bwitn5fc

bwitn5fc1#

根据日志,提供给文本小部件的String似乎为null。如果String有可能为null,解决方法是在String尚未加载的情况下为文本小部件分配一个默认String。在小部件上使用“if null”(??)操作符提供默认值。

Text(nullableString ?? 'Default String');

如果nullableStringnull,则将使用'Default String'。
那么你在文本Widget上得到null的原因是你在Text(getTitle(_myId))上赋值Future。函数getTitle()不会立即返回String。在加载到Widget之前获取值的一种方法是使用FutureBuilder

FutureBuilder<String>(
  future: getTitle(_myId), // fetch the String
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
    return Text(snapshot.data ?? 'Loading...');
  }
)

相关问题