Как реализовать поиск элементов, в списке который генерируется при помощи ListView.builder
У меня имеется страница которая отображает записи из базы данных в виде Элементов Card. Также для управления состоянием я пользуюсь пакетом Getx. Не знаю как реализовать поиск по этим элементам так чтобы эти элементы отсеивались в режиме реального времени с посимвольным вводом. В моем SearchBar имеется свойство OnChanged, к нему я планировал присоединиться.
Если нужны ещё какие то части моего кода, могу предоставить.
Код моего построителя элементов:
Widget build(BuildContext context) {
return GetX<ProductController>(
init: ProductController(),
builder: (controller) {
return FutureBuilder<List<ProductsCombined>>(
future: controller.productList.value,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.data.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) =>
ProductCards(
index: index,
snapshot: snapshot,
),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
},
);
}
Код моего контроллера:
class ProductController extends GetxController {
final productList = Future.value(<ProductsCombined>[]).obs;
@override
void onInit() {
fetchProducts();
super.onInit();
}
Future<List<ProductsCombined>> callDb() async {
return await DBHelper.db.getProducts();
}
void fetchProducts() async {
productList.value = callDb();
}
}
EDIT1: Изменил контроллер и некоторые другие места, не уверен насколько верно я сделал в плане оптимизации или ещё чего, но это работает. Привязал контроллер к событию onChanged, и элементы обновляются на экране только после завершения какого либо действия, например скрытие клавиатуры или нажатия кнопки принять, хотелось бы чтобы обновление было сразу при вводе символов
Измененный код контроллера:
class ProductController extends GetxController {
final productList = Future.value(<ProductsCombined>[]).obs;
Rx<Future<List<ProductsCombined>>> filterProduct =
Future.value(<ProductsCombined>[]).obs;
Future<void> searchChanged(String value) async {
if (value != null && value.isNotEmpty) {
List<ProductsCombined> s = await productList.value;
filterProduct = Future.value(s
.where((element) => (element.productName
.toLowerCase()
.contains(value.toLowerCase())))
.toList())
.obs;
} else
filterProduct = productList;
}
@override
void onInit() {
fetchProducts();
filterProduct = productList;
super.onInit();
}
Future<List<ProductsCombined>> callDb() async {
return await DBHelper.db.getProducts();
}
void fetchProducts() async {
productList.value = callDb();
}
}
Код в TextField:
TextField(
onChanged: (string) {
controller.searchChanged(string);
}
И в построителе элементов заменил:
return FutureBuilder<List<ProductsCombined>>(
future: controller.productList.value
На:
return FutureBuilder<List<ProductsCombined>>(
future: controller.filterProduct.value
