You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:20:28