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

如何在Flutter Web的PaginatedDataTable中实现搜索功能

在Flutter Web中给PaginatedDataTable添加搜索功能的实现方案

我来给你分享一个亲测有效的实现思路和完整代码示例,帮你搞定PaginatedDataTable的搜索功能~

核心逻辑其实很清晰:我们需要维护原始数据集和过滤后的数据集两份数据,用户输入搜索关键词时,实时对原始数据进行过滤,然后更新表格的数据源,就能实现动态匹配展示了。

1. 先准备数据模型和状态变量

首先定义你的数据模型,比如假设我们做一个用户列表:

class User {
  final int id;
  final String name;
  final String email;

  User({required this.id, required this.name, required this.email});
}

然后在页面的State类里,需要三个关键变量:

  • _originalUsers:保存所有原始数据,避免搜索时丢失全量数据
  • _filteredUsers:用于表格展示的过滤后数据
  • _searchController:监听用户搜索输入的控制器

2. 添加搜索输入框

在PaginatedDataTable的上方放一个搜索输入框,绑定控制器并监听输入变化:

TextField(
  controller: _searchController,
  decoration: InputDecoration(
    hintText: '搜索姓名/邮箱...',
    prefixIcon: const Icon(Icons.search),
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(8),
    ),
    contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
  ),
  onChanged: (keyword) => _filterData(keyword),
)

3. 实现数据过滤逻辑

写一个方法来处理关键词过滤,这里做的是模糊匹配,忽略大小写,你也可以根据需求改成精确匹配或其他规则:

void _filterData(String keyword) {
  if (keyword.trim().isEmpty) {
    // 关键词为空时,恢复展示全量数据
    setState(() {
      _filteredUsers = List.from(_originalUsers);
    });
    return;
  }

  // 按姓名或邮箱匹配关键词
  setState(() {
    _filteredUsers = _originalUsers.where((user) {
      final lowerKeyword = keyword.toLowerCase();
      return user.name.toLowerCase().contains(lowerKeyword) ||
          user.email.toLowerCase().contains(lowerKeyword);
    }).toList();
  });
}

4. 配置PaginatedDataTable的数据源

需要自定义一个DataTableSource子类,用过滤后的数据集来生成表格行:

class _UserTableSource extends DataTableSource {
  final List<User> users;

  _UserTableSource(this.users);

  @override
  DataRow getRow(int index) {
    final user = users[index];
    return DataRow.byIndex(
      index: index,
      cells: [
        DataCell(Text(user.id.toString())),
        DataCell(Text(user.name)),
        DataCell(Text(user.email)),
      ],
    );
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => users.length;

  @override
  int get selectedRowCount => 0;
}

然后在build方法里,用过滤后的数据集初始化数据源:

final tableSource = _UserTableSource(_filteredUsers);

return PaginatedDataTable(
  header: const Text('用户列表'),
  columns: const [
    DataColumn(label: Text('ID')),
    DataColumn(label: Text('姓名')),
    DataColumn(label: Text('邮箱')),
  ],
  source: tableSource,
  rowsPerPage: 10,
  // 可以根据需求添加其他配置,比如分页按钮样式等
);

5. 初始化和资源清理

在State的生命周期方法里初始化数据和控制器,记得销毁时释放资源:

@override
void initState() {
  super.initState();
  // 模拟加载原始数据(实际项目中可能是从接口获取)
  _originalUsers = [
    User(id: 1, name: '张三', email: 'zhangsan@example.com'),
    User(id: 2, name: '李四', email: 'lisi@example.com'),
    User(id: 3, name: '王五', email: 'wangwu@example.com'),
    User(id: 4, name: '赵六', email: 'zhaoliu@example.com'),
  ];
  _filteredUsers = List.from(_originalUsers);
  _searchController = TextEditingController();
}

@override
void dispose() {
  _searchController.dispose();
  super.dispose();
}

额外提示

  • 如果你的数据是异步加载的(比如从接口获取),记得在数据加载完成后更新_originalUsers和_filteredUsers,并调用setState刷新表格
  • 可以根据业务需求调整过滤规则,比如只匹配关键词开头、支持多字段组合搜索等
  • 这个方案在Flutter Web和移动端通用,不需要做平台适配

这样一套实现下来,用户输入关键词时,表格就会实时展示匹配的数据啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:13:50