如何定义Flutter/Dart中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
相关产品推荐
相关产品推荐

