(FLUTTER) ontap ListView (return listTile ()) с Streambuilder, приводящим к нулевым данным для наследования?
Привет, я пытаюсь создать простую базу данных в реальном времени с помощью Streambuilder, возвращая Listview.builder, который в нем является ListTile. Я хочу дать ListTile возможность переходить на другой дротик. что мне удалось сделать, однако, когда я пытаюсь передать элемент, он становится нулевым, но когда я пытаюсь его распечатать, он печатается в терминале.
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), в которой флаттер будет отображать список элементов при щелчке любого элемента в списке; он перенаправит пользователя к другому файлу дротика, в котором в этом файле дротика будет отображаться более подробное описание предмета.
Вот ошибка:
════════ 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
1 ответ
Судя по журналам, строка, предоставленная виджету «Текст», имеет нулевое значение. Если есть вероятность того, что строка может быть нулевой, обходной путь — назначить строку по умолчанию виджету «Текст» на случай, если строка еще не загружена. Используйте оператор if null (??) в виджете, чтобы указать значение по умолчанию.
Text(nullableString ?? 'Default String');
ЕслиnullableString
имеет значение null , то будет использоваться «Строка по умолчанию».
Тогда причина, по которой вы получаете нулевое значение в текстовом виджете, заключается в том, что вы назначаетеFuture
наText(getTitle(_myId))
. ФункцияgetTitle()
не возвращает строку мгновенно. Один из способов получения значения перед его загрузкой в виджет — использованиеFutureBuilder
.
FutureBuilder<String>(
future: getTitle(_myId), // fetch the String
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
return Text(snapshot.data ?? 'Loading...');
}
)