Пустая страница состояния и проблемы с навигатором?
Я хочу реализовать пустую страницу состояния в приложении Flutter, когда лента новостей пуста.
Когда в ленте нет активности, я хочу показать "нет активности". Когда в базе данных есть данные, я хочу загрузить их из StreamBuilder
в ListView.builder
Я пытаюсь реализовать с:
child: StreamBuilder(
stream: collection.snapshots(),
builder: (context, snapshot) {
if(snapshot.hasData) {
return ListView.builder(
itemBuilder: (context, index) =>
build(context, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
);
} else {
return _emptyStateWidget();
}
Я должен вернуть что-то в операторе else, потому что иногда в снимке не будет данных, поэтому будет выдано сообщение об ошибке, при котором Widget вернет ноль.
Но это вызывает проблемы с деревом виджетов. Потому что, если я попытаюсь использовать Navigator.push в build
Виджет позже:
Widget build(BuildContext context, DocumentSnapshot document) {
…
FlatButton(
onPressed: () async {
await function(document);
if(validated == true) {
await Navigator.push(context, new MaterialPageRoute(
builder: (BuildContext context) =>
new Screen(documentInfo: documentInfo)));
}
Ошибка выдана:
Поиск предка деактивированного виджета небезопасен. На этом этапе состояние дерева элементов виджета больше не является стабильным. Чтобы безопасно ссылаться на предка виджета в его методе dispose(), сохраните ссылку на предка, вызвав метод attributeitFromWidgetOfExactType() в виджете didChangeDependencies().
Есть ли способ избежать этого, чтобы не выдавалась ошибка?
По какой-то причине, если я позвоню Navigator.push
прежде чем ждать function(document)
нет ошибки. Но я не могу допустить этого, потому что он должен выполнять проверку данных в функции и только перемещаться в случае успеха.
Спасибо!
ОБНОВИТЬ:
После дополнительных испытаний я думаю, что проблема вызвана StreamBuilder
, Он восстанавливает всякий раз, когда получает новое событие. Так что это вызывает проблему при звонке Navigator.push
и это получит новое событие, поэтому попытайтесь восстановить.
Как решить? Можно остановить StreamBuilder
от перестроить потомка?
1 ответ
Это происходит потому, что вы пытаетесь перейти куда-то еще, пока ваше дерево виджетов еще строится.
Вы должны переместить Navigation.push
слушателю потока, например, в вашем initState
,
void initState() {
super.initState();
collection.snapshots.listen((data){
if(validated == true) {
await Navigator.push(context, new MaterialPageRoute(
builder: (BuildContext context) =>
new Screen(documentInfo: documentInfo)));
}
});
}