Как предоставить BLoC (с flutter_bloc) для `showSearch`

Я использую пакет flutter_bloc для управления состоянием. Я хочу создать экран поиска и нашел функцию showSearch Flutter, и у меня возникли проблемы с предоставлением экземпляра BLoC для создаваемой ListView моей SearchDelegate реализации. Наконец-то я заставил это работать, но хотел бы спросить, как лучше всего это сделать. Вот код (отрывки, начиная с кнопки, помещенной в AppBar в Scaffold):

class ItemSearchButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return IconButton(
      icon: Icon(Icons.search),
      onPressed: () {
        final itemListBloc = context.bloc<ItemListBloc>();
        showSearch(
          context: context,
          delegate: _ItemSearchDelegate(itemListBloc),
        );
      },
    );
  }
}

class _ItemSearchDelegate extends SearchDelegate<String> {
  final ItemListBloc itemListBloc;

  _ItemSearchDelegate(this.itemListBloc);

  // other overridden methods

  @override
  Widget buildSuggestions(BuildContext context) {
    return BlocProvider.value(
      value: itemListBloc,
      child: ItemListWidget(),
    );
  }
}

По сути, контекст, который вызывает метод showSearch, имеет правильный экземпляр BLoC, но он недоступен в моей реализации SearchDelegate, если я не предоставлю его снова явно в buildSuggestions.

Почему BLoC по умолчанию недоступен? Функция showSearch внутренне подталкивает новый Navigator Route, это проблема?

Каков канонический подход к таким вещам?


person wujek    schedule 23.05.2020    source источник


Ответы (2)


Да, при изменении маршрута buildContext тоже меняется. Итак, вы должны представить этот блок новому контексту. Просто оберните свою страницу там, где вы хотите перемещаться, с помощью BlocProvider:

Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => 
BlocProvider(create: Mybloc(),child:MyPage()); 
person Kiran Bhandari    schedule 23.05.2020
comment
Проблема в том, что навигация осуществляется функцией showSearch, т.е. я не могу ее изменить. Я уже без проблем делаю то, что вы говорите, для своих маршрутов. - person wujek; 23.05.2020

В конце концов, он работает так, как задумано - отправленный маршрут имеет новый контекст, который не является дочерним по отношению к контексту, в котором есть мой BLoC, он является дочерним по отношению к Navigator. Решение состоит в том, чтобы либо сделать то, что я делал изначально - явно передать BLoC в качестве аргумента конструктора, - либо убедиться, что контекст Navigator имеет BLoC, что я в конечном итоге и сделал; для этого убедитесь, что Navigator является дочерним элементом (Multi)BlocProvider.

person wujek    schedule 13.12.2020