Flutter动态搜索下拉选择插件dynamic_searchable_drop_down的使用
Flutter 动态搜索下拉选择插件 dynamic_searchable_drop_down 的使用
简介
Flutter 简单且健壮的下拉搜索插件,具有项目搜索功能,可以使用离线项目列表或过滤 URL 进行轻松定制。
关键特性
- 同步和/或异步项目(在线、离线、数据库等)
- 可搜索的下拉框
- 三种下拉模式:菜单/底部表单/模态底部表单/对话框
- 单选和多选
- 材料设计下拉框
- 易于自定义的用户界面
- 处理浅色和深色主题
- 轻松实现到无状态小部件
- 支持多级项目
packages.yaml
dropdown_search: <latest version>
导入
import 'package:dropdown_search/dropdown_search.dart';
简单实现
DropdownSearch<String>(
popupProps: PopupProps.menu(
showSelectedItems: true,
disabledItemFn: (String s) => s.startsWith('I'),
),
items: ["Brazil", "Italia (Disabled)", "Tunisia", 'Canada'],
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
labelText: "Menu mode",
hintText: "country in menu mode",
),
),
onChanged: print,
selectedItem: "Brazil",
)
DropdownSearch<String>.multiSelection(
items: ["Brazil", "Italia (Disabled)", "Tunisia", 'Canada'],
popupProps: PopupPropsMultiSelection.menu(
showSelectedItems: true,
disabledItemFn: (String s) => s.startsWith('I'),
),
onChanged: print,
selectedItems: ["Brazil"],
)
自定义显示字段 (itemAsString)
DropdownSearch<UserModel>(
asyncItems: (String filter) => getData(filter),
itemAsString: (UserModel u) => u.userAsStringByName(),
onChanged: (UserModel? data) => print(data),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(labelText: "User by name"),
),
)
DropdownSearch<UserModel>(
asyncItems: (String filter) => getData(filter),
itemAsString: (UserModel u) => u.userAsStringById(),
onChanged: (UserModel? data) => print(data),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(labelText: "User by id"),
),
)
自定义筛选函数
DropdownSearch<UserModel>(
filterFn: (user, filter) =>
user.userFilterByCreationDate(filter),
asyncItems: (String filter) => getData(filter),
itemAsString: (UserModel u) => u.userAsStringByName(),
onChanged: (UserModel? data) => print(data),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(labelText: "Name"),
),
)
自定义搜索模式
DropdownSearch<UserModel>(
popupProps: PopupProps.bottomSheet(),
dropdownSearchDecoration: InputDecoration(labelText: "Name"),
asyncItems: (String filter) => getData(filter),
itemAsString: (UserModel u) => u.userAsString(),
onChanged: (UserModel? data) => print(data),
)
验证
DropdownSearch(
items: ["Brazil", "France", "Tunisia", "Canada"],
dropdownSearchDecoration: InputDecoration(labelText: "Name"),
onChanged: print,
selectedItem: "Tunisia",
validator: (String? item) {
if (item == null)
return "Required field";
else if (item == "Brazil")
return "Invalid item";
else
return null;
},
)
使用 Dio 包进行端点实现
DropdownSearch<UserModel>(
dropdownSearchDecoration: InputDecoration(labelText: "Name"),
asyncItems: (String filter) async {
var response = await Dio().get(
"http://5d85ccfb1e61af001471bf60.mockapi.io/user",
queryParameters: {"filter": filter},
);
var models = UserModel.fromJsonList(response.data);
return models;
},
onChanged: (UserModel? data) {
print(data);
},
)
布局自定义
你可以自定义 DropdownSearch 及其项目的布局。
https://github.com/salim-lachdhaf/searchable_dropdown/tree/master/example#custom-layout-endpoint-example
完整文档 https://pub.dev/documentation/dropdown_search/latest/dropdown_search/DropdownSearch-class.html
注意事项
要使用模板作为项目类型,并且不想使用自定义函数 itemAsString 和 compareFn,则需要实现 toString、equals 和 hashCode,如下所示:
class UserModel {
final String id;
final DateTime createdAt;
final String name;
final String avatar;
UserModel({this.id, this.createdAt, this.name, this.avatar});
factory UserModel.fromJson(Map<String, dynamic> json) {
if (json == null) return null;
return UserModel(
id: json["id"],
createdAt:
json["createdAt"] == null ? null : DateTime.parse(json["createdAt"]),
name: json["name"],
avatar: json["avatar"],
);
}
static List<UserModel> fromJsonList(List list) {
if (list == null) return null;
return list.map((item) => UserModel.fromJson(item)).toList();
}
///此方法将防止覆盖 toString
String userAsString() {
return '#${this.id} ${this.name}';
}
///此方法将防止覆盖 toString
bool userFilterByCreationDate(String filter) {
return this.createdAt.toString().contains(filter);
}
///自定义比较函数以检查两个用户是否相等
bool isEqual(UserModel model) {
return this.id == model.id;
}
[@override](/user/override)
String toString() => name;
}
查看更多示例
https://github.com/salim-lachdhaf/searchable_dropdown/tree/master/example
支持
如果该插件对你有用,帮助你交付应用,节省了大量时间,或者你想支持该项目,我很感激你能买杯咖啡支持我。
许可证
MIT
完整示例代码
import 'package:dynamic_searchable_drop_down/dynamic_searchable_drop_down.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
themeMode: ThemeMode.dark,
darkTheme: ThemeData(brightness: Brightness.light),
debugShowCheckedModeBanner: false,
title: 'DropDown Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Searchable Drop Down'),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
height: 50,
),
SearchableDropdown(
disabledColor: Colors.blue,
hint: '-Select-',
outlineColor: Colors.black,
dropDownList: const [
'India',
'America',
'United Kingdom',
'Norway'
],
onSelected: (val) {
debugPrint('value is $val');
},
),
const SizedBox(
height: 50,
),
],
),
),
),
);
}
}
更多关于Flutter动态搜索下拉选择插件dynamic_searchable_drop_down的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动态搜索下拉选择插件dynamic_searchable_drop_down的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
dynamic_searchable_drop_down 是一个 Flutter 插件,它提供了一个可搜索的下拉选择框。用户可以输入文本进行过滤,并从下拉列表中选择一个选项。这个插件非常适合需要在大量选项中进行选择的场景。
安装插件
首先,你需要在 pubspec.yaml 文件中添加 dynamic_searchable_drop_down 插件的依赖:
dependencies:
flutter:
sdk: flutter
dynamic_searchable_drop_down: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get 来安装插件。
使用示例
下面是一个简单的使用示例,展示了如何在 Flutter 应用中使用 dynamic_searchable_drop_down 插件。
import 'package:flutter/material.dart';
import 'package:dynamic_searchable_drop_down/dynamic_searchable_drop_down.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Dynamic Searchable Dropdown Example'),
),
body: Center(
child: SearchableDropdownExample(),
),
),
);
}
}
class SearchableDropdownExample extends StatefulWidget {
[@override](/user/override)
_SearchableDropdownExampleState createState() => _SearchableDropdownExampleState();
}
class _SearchableDropdownExampleState extends State<SearchableDropdownExample> {
List<String> items = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig', 'Grape'];
String selectedItem;
[@override](/user/override)
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: DynamicSearchableDropdown<String>(
items: items,
hint: 'Select an item',
onChanged: (value) {
setState(() {
selectedItem = value;
});
},
selectedItem: selectedItem,
),
);
}
}
参数说明
items: 一个包含所有可选项的列表。hint: 在没有选择任何项时显示的提示文本。onChanged: 当用户选择一个项时调用的回调函数。selectedItem: 当前选中的项。
自定义样式
你可以通过传递额外的参数来自定义下拉框的样式,例如:
DynamicSearchableDropdown<String>(
items: items,
hint: 'Select an item',
onChanged: (value) {
setState(() {
selectedItem = value;
});
},
selectedItem: selectedItem,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Fruits',
),
itemBuilder: (context, item) {
return ListTile(
title: Text(item),
);
},
);
处理复杂对象
如果你需要处理复杂对象而不仅仅是字符串,你可以使用 value 和 displayValue 来分别表示对象的实际值和显示值:
class Fruit {
final String name;
final String color;
Fruit(this.name, this.color);
}
class SearchableDropdownExample extends StatefulWidget {
[@override](/user/override)
_SearchableDropdownExampleState createState() => _SearchableDropdownExampleState();
}
class _SearchableDropdownExampleState extends State<SearchableDropdownExample> {
List<Fruit> items = [
Fruit('Apple', 'Red'),
Fruit('Banana', 'Yellow'),
Fruit('Cherry', 'Red'),
Fruit('Date', 'Brown'),
Fruit('Elderberry', 'Purple'),
Fruit('Fig', 'Purple'),
Fruit('Grape', 'Green'),
];
Fruit selectedItem;
[@override](/user/override)
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: DynamicSearchableDropdown<Fruit>(
items: items,
hint: 'Select a fruit',
onChanged: (value) {
setState(() {
selectedItem = value;
});
},
selectedItem: selectedItem,
value: (item) => item,
displayValue: (item) => item.name,
),
);
}
}

