Я пытаюсь динамически обновлять ListView в зависимости от содержимого TextField (панели поиска).
ListView находится внутри виджета «ScenariosList» и содержит список «Scenarios», который является пользовательским виджетом, содержащим заголовок, содержимое и другие фрагменты данных (не очень релевантные, но полезные для контекста). Его содержимое извлекается из базы данных через "ScenariosBloc".
TextField содержится в виджете «SearchBar».
Цель состоит в том, чтобы содержимое ListView изменялось при каждом обнаружении изменения в TextField.
В настоящее время я использую два отдельных блока. ScenariosBloc извлекает все сценарии из базы данных, а FilterScenariosBloc заставляет List отображать виджет, показывающий сценарий, если его заголовок содержит строку в TextView в панели поиска.
Я использую для этого вложенные StreamBuilders (см. Код ниже).
ScenariosList.dart
// build individual scenario cards
Widget _buildScenarioListItem(Scenario scen, String filter) {
if (!(filter == null || filter == "")) {
print("null filter");
if (!(scen.title.contains(filter))) {
print("match!");
return ScenarioCard(scen);
}
}
return Container();
}
Widget _buildScenarioList(BuildContext context) {
return StreamBuilder(
stream: scenarioBloc.scenarios,
builder: (BuildContext context,
AsyncSnapshot<List<Scenario>> scenariosSnapshot) {
if (!scenariosSnapshot.hasData) {
return CircularProgressIndicator();
}
return StreamBuilder(
stream: filterScenariosBloc.filterQuery,
initialData: "",
builder: (BuildContext context, AsyncSnapshot filterSnapshot) {
if(!filterSnapshot.hasData) return CircularProgressIndicator();
print("Scenarios Snapshot: ${scenariosSnapshot.toString()}");
print("Filter Snapshot: ${filterSnapshot.toString()}");
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.all(0),
shrinkWrap: true,
itemCount: scenariosSnapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Scenario scen = scenariosSnapshot.data[index];
return _buildScenarioListItem(scen, filterSnapshot.data);
},
);
});
});
}
}
SearchBar.dart
метод onChanged текстового поля содержит:
// function to filter the scenarios depending on the users input.
void filterSearchResults(String query) {
_filterScenariosBloc.doFilter(query);
}
FilterScenariosBloc.dart
class FilterScenariosBloc {
// stream - only need one listener
final _searchController = StreamController<String>.broadcast();
// output stream
get filterQuery => _searchController.stream;
FilterScenariosBloc() {
doFilter(" ");
}
doFilter(String query) {
_searchController.sink.add(query);
}
}
Пользовательский ввод отправляется на FilterScenariosBloc все нормально, но статус filterSnapshot
всегда равен connectionState.waiting.
Любые идеи о том, как я могу решить эту проблему?