Flutter现有下拉按钮添加搜索功能求助
带搜索功能的国旗下拉列表解决方案
直接替换你现有代码中的DropdownButton为DropdownSearch组件,以下是适配后的完整代码:
Card( margin: EdgeInsets.zero, child: Container( padding: EdgeInsets.symmetric(horizontal: screenWidth * 0.05), child: Obx(() { return DropdownSearch<String>( // 绑定当前选中的国家名称 selectedItem: countryController.countryName.value, isExpanded: true, // 搜索框样式配置 searchFieldProps: TextFieldProps( decoration: InputDecoration( hintText: "搜索国家", border: InputBorder.none, ), ), // 自定义下拉项UI,和你原来的结构一致 itemBuilder: (context, itemName, isSelected) { final country = countryController.countryList.firstWhere((c) => c.countryName == itemName); return Row( children: [ Image.network( country.flagUrl, width: screenWidth * 0.09, fit: BoxFit.contain, ), SizedBox(width: screenWidth * 0.03), Expanded( child: Text( country.countryName, style: TextStyle( fontSize: screenWidth * 0.045, fontWeight: FontWeight.w500, ), ), ), ], ); }, // 选中后顶部显示的UI selectedItemBuilder: (context, itemName) { final country = countryController.countryList.firstWhere((c) => c.countryName == itemName); return Row( children: [ Image.network( country.flagUrl, width: screenWidth * 0.09, fit: BoxFit.contain, ), SizedBox(width: screenWidth * 0.03), Expanded( child: Text( country.countryName, style: TextStyle( fontSize: screenWidth * 0.045, fontWeight: FontWeight.w500, ), ), ), ], ); }, // 去掉默认下划线,匹配你原来的样式 dropdownDecoratorProps: DropDownDecoratorProps( dropdownSearchDecoration: InputDecoration( border: InputBorder.none, suffixIcon: Icon(Icons.keyboard_arrow_down_outlined), suffixIconConstraints: BoxConstraints( minWidth: screenWidth * 0.06, minHeight: screenWidth * 0.06, ), ), ), elevation: 16, // 提取所有国家名称作为数据源 items: countryController.countryList.map((c) => c.countryName).toList(), // 选中回调和你原来的逻辑一致 onChanged: (value) { if (value != null) { countryController.selectIntlCountry(value); } }, ); }), ), )
优化建议(可选)
如果你想避免每次查找CountryModel的开销,可以直接绑定CountryModel对象:
- 在你的controller中添加一个可观察变量:
final selectedCountry = Rx<CountryModel?>(null);
- 修改
DropdownSearch为DropdownSearch<CountryModel>:
DropdownSearch<CountryModel>( selectedItem: countryController.selectedCountry.value, items: countryController.countryList, itemBuilder: (context, country, isSelected) { return Row( children: [ Image.network(country.flagUrl, width: screenWidth * 0.09, fit: BoxFit.contain), SizedBox(width: screenWidth * 0.03), Expanded(child: Text(country.countryName, style: TextStyle(fontSize: screenWidth * 0.045, fontWeight: FontWeight.w500))), ], ); }, selectedItemBuilder: (context, country) { return Row( children: [ Image.network(country.flagUrl, width: screenWidth * 0.09, fit: BoxFit.contain), SizedBox(width: screenWidth * 0.03), Expanded(child: Text(country.countryName, style: TextStyle(fontSize: screenWidth * 0.045, fontWeight: FontWeight.w500))), ], ); }, onChanged: (value) { if (value != null) { countryController.selectedCountry.value = value; countryController.selectIntlCountry(value.countryName); } }, // 其他配置同上 )
常见问题排查
- 确保已在
pubspec.yaml中添加依赖:dropdown_search: ^5.0.6(可替换为最新版本) - 如果搜索匹配规则不符合需求,可自定义
filterFn参数:
// String版本的自定义过滤 filterFn: (itemName, filter) { return itemName.toLowerCase().contains(filter.toLowerCase()); } // CountryModel版本的自定义过滤 filterFn: (country, filter) { return country.countryName.toLowerCase().contains(filter.toLowerCase()); }
内容的提问来源于stack exchange,提问作者TecSy
相关产品推荐
相关产品推荐

