Flutter中dropdown_search库加载更多用户后列表不刷新问题求助
问题分析与解决方案
你的问题核心在于:DropdownSearch弹窗内的列表未在分页加载新数据后实时刷新——asyncItems每次调用都会重新发起请求,且未将新数据合并到现有列表;同时滚动触发加载后,没有正确通知DropdownSearch的弹窗列表更新状态。
关键修改点
- 累积分页数据,避免每次请求重置列表
- 添加加载锁,防止重复请求
- 优化滚动监听逻辑,确保状态更新同步到弹窗
- 区分首次加载、分页加载和搜索场景的逻辑
具体代码修改
1. 新增状态变量
在类中添加以下变量,控制加载状态和数据边界:
bool _isLoading = false; // 防止重复触发加载 bool _hasMoreData = true; // 标记是否还有更多数据可加载
2. 重构分页加载方法
修改_loadValueOptionListSpecificPeople,支持分页累积数据,并处理搜索重置逻辑:
Future<List<ListValueOptionList>> _loadValueOptionListSpecificPeople({String filter = "", bool isSearch = false}) async { if (_isLoading) return []; _isLoading = true; try { // 搜索时重置页码与列表,避免分页数据干扰搜索结果 if (isSearch) { pageCounter = 0; listValueOptionsUserDelegation?.clear(); _hasMoreData = true; } // 调用API,传入当前页码与搜索关键词 final response = await yourApiService.getUsers(page: pageCounter, filter: filter); final newItems = response.data.map((json) => ListValueOptionList.fromJson(json)).toList(); if (newItems.isEmpty) { _hasMoreData = false; // 无新数据,标记终止加载 } else { // 将新数据合并到全局列表 listValueOptionsUserDelegation ??= []; listValueOptionsUserDelegation.addAll(newItems); pageCounter++; } return listValueOptionsUserDelegation; } catch (e) { print("加载用户列表失败: $e"); _hasMoreData = false; return listValueOptionsUserDelegation ?? []; } finally { _isLoading = false; setState(() {}); // 更新状态触发UI刷新 // 强制刷新DropdownSearch弹窗列表 myKey.currentState?.updatePopup(); } }
3. 优化滚动监听逻辑
调整initState中的滚动监听,添加加载状态与数据边界判断:
@override void initState() { super.initState(); _scrollController.addListener(() { // 仅在未加载、还有数据、且滚动到底部时触发分页 if (!_isLoading && _hasMoreData && _scrollController.position.pixels == _scrollController.position.maxScrollExtent) { _loadValueOptionListSpecificPeople(); } }); }
4. 调整DropdownSearch的asyncItems逻辑
区分搜索与普通分页场景,避免重复请求:
asyncItems: (filter) async { if (filter.isNotEmpty) { // 有搜索关键词时,触发搜索模式 return await _loadValueOptionListSpecificPeople(filter: filter, isSearch: true); } else { // 无搜索时,返回已累积的列表(首次加载则发起请求) if (listValueOptionsUserDelegation == null || listValueOptionsUserDelegation.isEmpty) { return await _loadValueOptionListSpecificPeople(); } return listValueOptionsUserDelegation; } },
5. 移除破坏性数据修改
删除specificPeople方法中对原始列表的直接修改:
// 移除这行代码,避免破坏全局列表数据 // listValueOptionList.removeWhere((element) => userLoad.id.stringOf == element.idValue);
建议改为在API请求时过滤已选中用户,或在itemBuilder中隐藏已选中项:
itemBuilder: (context, list, isSelected){ // 隐藏已选中的用户 if (userAlreadyUse.contains(list.idValue)) { return SizedBox.shrink(); } return Container( child: ListTile( selected: isSelected, title: Text( list?.listValueDescription, style: TextStyle(color: appStyleMode.blackWhiteColor), ), ), ); },
内容的提问来源于stack exchange,提问作者PierreB
相关产品推荐
相关产品推荐

