I am using DropdownSearch with lazy loading inside a modal bottom sheet in Flutter. The list of items is fetched using Bloc (LocationMasterCubit), and I am handling infinite scrolling to load more items dynamically.
The problem is that when I call setState(() {}); after fetching more items, the dropdown list does not update correctly. It seems like setState is not triggering a rebuild for the dropdown items.
Code Snippet: Here’s how I implemented the lazy loading inside DropdownSearch:
BlocBuilder<LocationMasterCubit, LocationMasterState>(
builder: (context, state) {
return DropdownSearch<String>(
suffixProps: DropdownSuffixProps(
dropdownButtonProps: DropdownButtonProps(
iconClosed: const Icon(Icons.keyboard_arrow_down),
iconOpened: const Icon(Icons.keyboard_arrow_up),
iconSize: 20.sp,
color: ColorManager.black,
),
),
selectedItem: locationMaster?.costCenter1 ?? costCenter1,
decoratorProps: const DropDownDecoratorProps(
decoration: InputDecoration(labelText: 'Cost Center 1'),
),
items: (f, loadProps) => locationMasterCubit.costCenter1?.result ?? [],
itemAsString: (item) => item,
onChanged: (selectedItem) {
setState(() {
costCenter1 = selectedItem!;
});
},
popupProps: PopupProps.menu(
itemBuilder: (context, item, isDisabled, isSelected) {
return ListTile(
title: Text(item),
);
},
constraints: BoxConstraints(maxHeight: 150.h),
listViewProps: ListViewProps(
controller: scrollController,
),
searchFieldProps: TextFieldProps(
decoration: const InputDecoration(hintText: 'Search...'),
onChanged: (value) {
locationMasterCubit.getCostCenter1(search: value, page: 1);
},
),
showSearchBox: true,
),
);
},
);
ScrollController (Handling Pagination):
scrollController.addListener(() async {
if (scrollController.position.pixels >=
scrollController.position.maxScrollExtent) {
currentPage++;
await locationMasterCubit.getCostCenter1(page: currentPage);
setState(() {}); // Not updating the dropdown items
}
});
Issue: When I scroll to the bottom, getCostCenter1(page: currentPage) fetches more items successfully.
However, DropdownSearch does not update to show the newly fetched items.
setState(() {}) is called, but it does not trigger a rebuild.
Cubit logic:
Future<void> getCostCenter1({String? search, required int page}) async {
try {
if (!isSearching) {
isSearching = true;
page == 1 ? emit(_FetchingData()) : emit(_FetchingNextData());
if (page == 1) costCenter1 = null;
final response = await locationMasterApiService.getCostCenter1(
search: search, page: page);
final costCenter1List = <String>[
if (costCenter1 != null) ...costCenter1!.result,
...response['items'].map((cost) => cost)
];
costCenter1 =
PaginatedResponse<String>.fromJson(response, costCenter1List);
isSearching = false;
emit(_FetchedData());
}
} on ApiException catch (e) {
isSearching = false;
emit(
_LocationMasterFailed(
message: e.maybeWhen(
connectionException: (message, context) => message,
basic: (message, context) => message,
orElse: () => e.context!,
),
),
);
}
}
Question:
How can I make sure DropdownSearch updates properly when new items are fetched? Should I use StatefulBuilder, BlocListener, or another approach?
Any help would be appreciated!