Flutter课程列表页面如何添加搜索过滤功能?
Flutter课程列表搜索过滤实现方案
核心思路
维护两个列表:一个存原始完整课程数据(后端请求返回的全部内容),另一个存过滤后的展示数据。监听搜索框输入内容,实时用输入值匹配原始列表的课程字段(比如标题、讲师名),更新展示列表并刷新UI。
具体实现步骤
1. 状态类变量准备
用StatefulWidget承载页面,在状态类里定义关键变量:
// 存储从后端获取的全部课程数据 List<Course> _allCourses = []; // 存储过滤后要展示的课程数据 List<Course> _filteredCourses = []; // 监听搜索输入的控制器 final TextEditingController _searchController = TextEditingController();
(注:假设你已经定义了Course数据模型,包含title、instructor等需要匹配的字段)
2. 添加搜索栏UI
把搜索栏放在列表上方,样式可以调整成你想要的圆角、阴影效果:
TextField( controller: _searchController, onChanged: (value) => _filterCourses(value), decoration: InputDecoration( hintText: "搜索课程/讲师...", prefixIcon: const Icon(Icons.search), border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.grey[200], contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), ), )
3. 实现过滤逻辑
在状态类里写过滤方法,支持忽略大小写的模糊匹配:
void _filterCourses(String query) { if (query.isEmpty) { // 输入为空时恢复展示全部课程 _filteredCourses = List.from(_allCourses); } else { final lowerQuery = query.toLowerCase(); _filteredCourses = _allCourses.where((course) { // 可根据需求添加更多匹配字段,比如课程简介 return course.title.toLowerCase().contains(lowerQuery) || course.instructor.toLowerCase().contains(lowerQuery); }).toList(); } // 通知UI更新 setState(() {}); }
4. 初始化数据
在initState里发起后端请求,成功后同时初始化两个列表:
@override void initState() { super.initState(); _fetchCourses(); } Future<void> _fetchCourses() async { // 替换成你的实际请求逻辑,携带用户token final response = await http.get( Uri.parse("你的后端课程接口地址"), headers: {"Authorization": "Bearer 你的用户token"}, ); if (response.statusCode == 200) { final List<dynamic> rawData = jsonDecode(response.body); _allCourses = rawData.map((item) => Course.fromJson(item)).toList(); _filteredCourses = List.from(_allCourses); setState(() {}); } else { // 处理请求失败场景,比如弹提示 print("课程数据请求失败:${response.statusCode}"); } }
5. 渲染过滤后的列表
把原来ListView.builder的数据源换成_filteredCourses:
ListView.builder( itemCount: _filteredCourses.length, itemBuilder: (context, index) { final course = _filteredCourses[index]; return ListTile( title: Text(course.title), subtitle: Text(course.instructor), // 保留你原来的其他列表项属性 ); }, )
6. 资源清理
在页面销毁时释放控制器,避免内存泄漏:
@override void dispose() { _searchController.dispose(); super.dispose(); }
额外优化建议
- 如果课程数量大,可加防抖处理:比如延迟300ms再执行过滤,避免输入时频繁触发UI更新(可以用
Timer实现简单防抖)。 - 搜索结果为空时,添加提示UI,比如显示
Center(child: Text("未找到匹配课程"))。
内容的提问来源于stack exchange,提问作者idk
相关产品推荐
相关产品推荐

