如何基于现有代码在Flutter中实现用户名称搜索与建议功能
解决Flutter搜索筛选及建议功能实现问题
核心优化方向
- 避免重复请求后端接口:初始化时一次性拉取用户数据,而非每次构建界面都发起请求
- 实现用户名实时筛选逻辑:根据搜索框输入的
query过滤用户列表 - 区分搜索结果与建议展示:
buildSuggestions实时响应输入变化,buildResults展示最终筛选结果
修改后的完整代码
class CustomSearchDelegate extends SearchDelegate { AllBackEnds _allBackEnds = AllBackEnds(); late Future<List<Map<String, dynamic>>> _usersFuture; // 初始化时提前获取用户数据,避免重复请求 CustomSearchDelegate() { _usersFuture = _allBackEnds.getUsers().then((list) => list.cast<Map<String, dynamic>>()); } @override List<Widget> buildActions(BuildContext context) { return [ IconButton( onPressed: () { if (query.isEmpty) { close(context, null); } else { query = ''; } }, icon: Icon(Icons.clear)), ]; } @override Widget buildLeading(BuildContext context) => IconButton( icon: BackButtonIcon(), onPressed: () { close(context, null); }, ); // 筛选用户列表的工具方法 List<Map<String, dynamic>> _filterUsers(List<Map<String, dynamic>> users) { if (query.isEmpty) return users; // 忽略大小写匹配用户名,可按需改为开头匹配(startsWith)或其他规则 return users.where((user) => user['name'].toLowerCase().contains(query.toLowerCase()) ).toList(); } @override Widget buildResults(BuildContext context) { return FutureBuilder<List<Map<String, dynamic>>>( future: _usersFuture, builder: (context, snapshot) { if (!snapshot.hasData) { return CustProgIndicator(); } else { final filteredUsers = _filterUsers(snapshot.data!); return ListView.builder( itemCount: filteredUsers.length, shrinkWrap: true, itemBuilder: (context, int index) { return CustomWid(data: filteredUsers[index]); }, ); } }); } @override Widget buildSuggestions(BuildContext context) { return FutureBuilder<List<Map<String, dynamic>>>( future: _usersFuture, builder: (context, snapshot) { if (!snapshot.hasData) { return CustProgIndicator(); } else { final filteredUsers = _filterUsers(snapshot.data!); // 可选:给匹配的文本添加高亮,提升体验 return ListView.builder( itemCount: filteredUsers.length, shrinkWrap: true, itemBuilder: (context, int index) { final user = filteredUsers[index]; final name = user['name']; final matchPos = name.toLowerCase().indexOf(query.toLowerCase()); Widget nameWidget = Text(name); // 存在匹配时高亮显示对应文本 if (matchPos != -1 && query.isNotEmpty) { nameWidget = RichText( text: TextSpan( text: name.substring(0, matchPos), style: TextStyle(color: Colors.black), children: [ TextSpan( text: name.substring(matchPos, matchPos + query.length), style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold), ), TextSpan( text: name.substring(matchPos + query.length), style: TextStyle(color: Colors.black), ), ], ), ); } return ListTile( title: nameWidget, onTap: () { // 点击建议项填充搜索框并展示结果 query = name; showResults(context); }, ); // 若要保留原CustomWid,替换为:return CustomWid(data: user); }, ); } }); } }
关键细节说明
- 数据预加载:构造函数中初始化
_usersFuture,确保只请求一次后端接口,减少无效网络请求 - 筛选逻辑:
_filterUsers方法通过忽略大小写的包含匹配筛选用户,可根据业务需求调整匹配规则 - 建议项交互:点击建议项自动填充搜索框并触发结果展示,同时添加文本高亮增强用户感知
- 功能划分:严格遵循
SearchDelegate设计,buildSuggestions处理实时输入反馈,buildResults展示最终搜索结果
内容的提问来源于stack exchange,提问作者Bilal Sloni
相关产品推荐
相关产品推荐

