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

Flutter中SearchDelegate如何实现输入内容变化时实时查询数据库

解决方案

你可以通过以下两种方式实现搜索框输入变化的监听,两种方式都可以达到和TextField.onChanged一致的触发效果:

方式1:重写updateQuery方法(更灵活,推荐)

SearchDelegate内部自带updateQuery方法,每次用户增删搜索框字符时都会自动调用该方法,直接重写即可拿到最新的输入内容,按需执行数据库查询。建议搭配防抖逻辑避免频繁查询数据库影响性能。
修改后的完整代码如下:

import 'dart:async';
import 'package:flutter/material.dart';

class DataSearch extends SearchDelegate<String>{
  // 存储查询到的建议列表
  List<String> _suggestionList = [];
  // 防抖定时器
  Timer? _debounceTimer;

  @override
  void updateQuery(String newQuery) {
    super.updateQuery(newQuery);
    // 输入变化时先取消上一次未执行的查询任务
    if (_debounceTimer?.isActive ?? false) _debounceTimer!.cancel();
    // 延迟300ms执行查询,用户停止输入300ms后才触发查询,可自行调整时间
    _debounceTimer = Timer(const Duration(milliseconds: 300), () async {
      // 替换为你自己的数据库查询逻辑
      _suggestionList = await _queryFromDatabase(newQuery);
      // 通知UI刷新
      notifyListeners();
    });
  }

  @override
  List<Widget>? buildActions(BuildContext context) {
    return [
      IconButton(
          onPressed: () {query = '';},
          icon: const Icon(Icons.clear))
    ];
  }

  @override
  Widget? buildLeading(BuildContext context) {
    return IconButton(
        onPressed: (){close(context, '');},
        icon: AnimatedIcon(
          progress: transitionAnimation,
          icon: AnimatedIcons.menu_arrow
        ));
  }

  @override
  Widget buildResults(BuildContext context) {
    //TODO 基于选中的内容展示结果
    return Scaffold();
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    final showList = query.isEmpty ? [] : _suggestionList;

    return ListView.builder(
      itemBuilder: (context, index) => ListTile(
        onTap: () {
          // 点击建议项可直接填入搜索框并展示结果
          query = showList[index];
          showResults(context);
        },
        title: RichText(
          text: TextSpan(
              text: showList[index].substring(0, query.length),
              style: const TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
              children: [
                TextSpan(
                    text: showList[index].substring(query.length),
                    style: const TextStyle(color: Colors.grey))
              ]),
        ),
      ),
      itemCount: showList.length,
    );
  }

  @override
  void close(BuildContext context, String result) {
    // 销毁时取消定时器避免内存泄漏
    _debounceTimer?.cancel();
    super.close(context, result);
  }

  // 示例数据库查询方法,替换为你自己的实现
  Future<List<String>> _queryFromDatabase(String keyword) async {
    // 这里执行你的真实数据库查询逻辑
    await Future.delayed(const Duration(milliseconds: 100));
    return ['苹果', '香蕉', '橙子', '葡萄', '芒果']
        .where((element) => element.contains(keyword))
        .toList();
  }
}

方式2:直接在buildSuggestions中处理

如果不需要额外的逻辑控制,也可以直接在buildSuggestions方法中执行查询,该方法会在每次query更新时自动触发,同样需要加防抖逻辑避免频繁查询。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:54:06