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

如何定义Flutter/Dart中DropdownMenu的SearchCallback?求示例

Flutter DropdownMenu SearchCallback 实现示例

核心说明

DropdownMenu的onSearch参数接收的SearchCallback是一个函数,签名为:

List<DropdownMenuEntry<T>> Function(List<DropdownMenuEntry<T>> entries, String query)

它接收两个参数:

  • entries:原始的下拉菜单条目列表
  • query:用户通过输入框输入的搜索文本
    返回值是过滤后的条目列表。

完整代码示例(基础字符串选项)

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('带搜索的下拉菜单')),
        body: const Padding(
          padding: EdgeInsets.all(16.0),
          child: SearchableDropdown(),
        ),
      ),
    );
  }
}

class SearchableDropdown extends StatefulWidget {
  const SearchableDropdown({super.key});

  @override
  State<SearchableDropdown> createState() => _SearchableDropdownState();
}

class _SearchableDropdownState extends State<SearchableDropdown> {
  final TextEditingController _searchController = TextEditingController();
  final List<String> _allOptions = [
    'Flutter', 'Dart', 'Android', 'iOS',
    'Web', 'Desktop', 'Linux', 'Windows', 'macOS'
  ];
  String? _selectedValue;

  // 实现SearchCallback
  List<DropdownMenuEntry<String>> _filterEntries(
      List<DropdownMenuEntry<String>> entries, String query) {
    if (query.trim().isEmpty) return entries;
    // 大小写不敏感的模糊匹配
    return entries.where((entry) {
      return entry.label.toLowerCase().contains(query.toLowerCase());
    }).toList();
  }

  @override
  Widget build(BuildContext context) {
    final List<DropdownMenuEntry<String>> _entries = _allOptions
        .map((option) => DropdownMenuEntry(value: option, label: option))
        .toList();

    return DropdownMenu<String>(
      controller: _searchController,
      label: const Text('选择开发平台'),
      initialSelection: _selectedValue,
      dropdownMenuEntries: _entries,
      onSearch: _filterEntries, // 绑定搜索回调
      onSelected: (value) => setState(() => _selectedValue = value),
    );
  }

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

自定义模型的扩展示例

如果你的下拉选项是自定义模型,比如包含更多字段,可以这样调整过滤逻辑:

// 自定义模型类
class Platform {
  final String name;
  final String category;

  Platform(this.name, this.category);
}

// 对应的SearchCallback实现
List<DropdownMenuEntry<Platform>> _filterPlatformEntries(
    List<DropdownMenuEntry<Platform>> entries, String query) {
  if (query.trim().isEmpty) return entries;
  final lowerQuery = query.toLowerCase();
  return entries.where((entry) {
    final platform = entry.value;
    // 同时匹配名称和分类
    return platform.name.toLowerCase().contains(lowerQuery) ||
        platform.category.toLowerCase().contains(lowerQuery);
  }).toList();
}

关键注意点

  • 当query为空或空白时,建议直接返回原始条目,保证初始状态显示全部选项
  • 过滤逻辑可以根据需求调整:精确匹配、前缀匹配、多字段匹配等
  • 记得在StatefulWidget中正确销毁TextEditingController,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 07:57:13