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

如何在Flutter SearchDelegate中实现搜索过滤与排序功能?

解决方案

一、修复搜索无响应问题

当前代码直接使用原始的state.mTicket.cards列表,没有根据搜索框输入内容做过滤。需要利用SearchDelegate自带的query属性对列表进行筛选:

  1. 在buildResults中添加过滤逻辑:
@override
Widget buildResults(BuildContext context) {
  return BlocBuilder<CardListBloc, CardState>(
    builder: (context, state) {
      // 根据搜索关键词过滤卡片(不区分大小写)
      final filteredCards = state.mTicket.cards.where((card) {
        final nameLower = card.name.toLowerCase();
        final queryLower = query.toLowerCase();
        return nameLower.contains(queryLower);
      }).toList();

      return ListView.builder(
        itemCount: filteredCards.length,
        itemBuilder: (context, index) {
          final card = filteredCards[index];
          return Card(
            elevation: 4,
            shape: cardRadius(4),
            margin: EdgeInsets.only(left: 12, right: 12, top: index == 0 ? 12 : 0),
            child: Container(
              width: double.infinity,
              child: ListTile(
                title: Text(card.name),
                subtitle: Text(Jiffy(card.createdOn).MEd),
              ),
            ),
          );
        },
      );
    },
  );
}
  1. 补充提示:如果需要实时搜索(输入时即时更新结果),可以重写buildSuggestions方法,逻辑和buildResults一致,用于展示输入过程中的候选结果。

二、添加排序功能

1. 在SearchDelegate类中定义排序相关变量

// 定义排序类型枚举
enum SortType { nameAsc, nameDesc, dateNewest, dateOldest }

class YourSearchDelegate extends SearchDelegate {
  SortType _currentSortType = SortType.dateNewest; // 默认按最新创建时间排序

2. 添加排序切换按钮到搜索栏

重写appBarActions方法,添加排序选择按钮:

@override
List<Widget>? buildActions(BuildContext context) {
  return [
    PopupMenuButton<SortType>(
      icon: const Icon(Icons.sort),
      onSelected: (value) {
        _currentSortType = value;
        setState(() {}); // 更新UI触发重新排序
      },
      itemBuilder: (context) => [
        const PopupMenuItem(
          value: SortType.nameAsc,
          child: Text("名称升序"),
        ),
        const PopupMenuItem(
          value: SortType.nameDesc,
          child: Text("名称降序"),
        ),
        const PopupMenuItem(
          value: SortType.dateNewest,
          child: Text("最新创建"),
        ),
        const PopupMenuItem(
          value: SortType.dateOldest,
          child: Text("最早创建"),
        ),
      ],
    ),
  ];
}

3. 在过滤后执行排序逻辑

在buildResults中,对过滤后的列表添加排序处理:

// 封装排序方法
void sortCards(List<YourCardModel> cards) {
  switch (_currentSortType) {
    case SortType.nameAsc:
      cards.sort((a, b) => a.name.compareTo(b.name));
      break;
    case SortType.nameDesc:
      cards.sort((a, b) => b.name.compareTo(a.name));
      break;
    case SortType.dateNewest:
      cards.sort((a, b) => b.createdOn.compareTo(a.createdOn));
      break;
    case SortType.dateOldest:
      cards.sort((a, b) => a.createdOn.compareTo(b.createdOn));
      break;
  }
}

// 在buildResults中调用排序
final filteredCards = state.mTicket.cards.where((card) {
  final nameLower = card.name.toLowerCase();
  final queryLower = query.toLowerCase();
  return nameLower.contains(queryLower);
}).toList();

sortCards(filteredCards);

注意事项

  • 替换YourCardModel为你实际的卡片数据类型
  • 确保createdOn是可比较的日期类型(如DateTime)
  • 如果使用Bloc统一管理状态,也可以将排序逻辑迁移到Bloc中,避免在SearchDelegate中持有状态

内容的提问来源于stack exchange,提问作者behnami454

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:55:30