Пустая страница состояния и проблемы с навигатором?

Я хочу реализовать пустую страницу состояния в приложении 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)));
  }
});

}
Другие вопросы по тегам