Flutter下拉搜索插件dropdown_search的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter下拉搜索插件dropdown_search的使用

简介

Flutter DropdownSearch 是一个简单且响应式的下拉搜索组件,支持离线和在线项目列表、多级项目、四种下拉模式(菜单/底部表单/模态底部表单/对话框)、单选和多选等功能。它还支持自定义UI、处理浅色和深色主题,并且易于在无状态小部件中实现。

关键特性

  • 响应式小部件
  • 无限列表(懒加载)
  • 同步和异步项目(在线、离线、数据库等)
  • 可搜索下拉菜单
  • 支持多级项目
  • 四种下拉模式:Menu/ BottomSheet/ ModalBottomSheet / Dialog
  • 单选和多选
  • Material风格下拉菜单
  • 适应性UI:Material, iOS(即将推出)
  • 易定制UI - 无样板代码
  • 处理浅色和深色主题
  • 易于在无状态小部件中实现

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  dropdown_search: ^5.0.2

然后运行 flutter pub get 来安装插件。

导入

在 Dart 文件中导入 dropdown_search 包:

import 'package:dropdown_search/dropdown_search.dart';

简单示例

以下是一个简单的 DropdownSearch 实现示例:

DropdownSearch<String>(
  items: ["Item 1", "Item 2", "Item 3", "Item 4"],
  popupProps: PopupProps.menu(
    disabledItemFn: (item) => item == 'Item 3',
    fit: FlexFit.loose,
  ),
),

多选示例

以下是多选模式的示例:

DropdownSearch<String>.multiSelection(
  items: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
  dropdownBuilder: (ctx, selectedItem) => Icon(Icons.calendar_month_outlined, size: 54),
),

自定义项类型示例

以下是自定义项类型的示例,项类型为 (String, Color)

DropdownSearch<(String, Color)>(
  items: [
    ("Red", Colors.red),
    ("Black", Colors.black),
    ("Yellow", Colors.yellow),
    ('Blue', Colors.blue),
  ],
  compareFn: (item1, item2) => item1.$1 == item2.$1,
  popupProps: PopupProps.menu(
    menuProps: MenuProps(align: MenuAlign.bottomCenter),
    fit: FlexFit.loose,
    itemBuilder: (context, item, isDisabled, isSelected) => Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(item.$1, style: TextStyle(color: item.$2, fontSize: 16)),
    ),
  ),
  dropdownBuilder: (ctx, selectedItem) => Icon(Icons.face, color: selectedItem?.$2, size: 54),
),

对话框模式示例

以下是使用对话框模式的示例:

DropdownSearch<int>(
  items: List.generate(30, (i) => i + 1),
  decoratorProps: DropDownDecoratorProps(
    decoration: InputDecoration(labelText: "Dialog with title", hintText: "Select an Int"),
  ),
  popupProps: PopupProps.dialog(
    title: Container(
      decoration: BoxDecoration(color: Colors.deepPurple),
      alignment: Alignment.center,
      padding: EdgeInsets.symmetric(vertical: 16),
      child: Text(
        'Numbers 1..30',
        style: TextStyle(fontSize: 21, fontWeight: FontWeight.bold, color: Colors.white70),
      ),
    ),
    dialogProps: DialogProps(
      clipBehavior: Clip.antiAlias,
      shape: OutlineInputBorder(
        borderSide: BorderSide(width: 0),
        borderRadius: BorderRadius.circular(25),
      ),
    ),
  ),
),

布局定制

你可以根据需要自定义 DropdownSearch 和其项目的布局。更多示例可以参考 GitHub 示例

完整示例代码

以下是一个完整的示例代码,展示了如何在应用中使用 DropdownSearch 插件:

import 'package:dio/dio.dart';
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';

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

Future<List<UserModel>> getData(filter) async {
  var response = await Dio().get(
    "https://63c1210999c0a15d28e1ec1d.mockapi.io/users",
    queryParameters: {"filter": filter},
  );

  final data = response.data;
  if (data != null) {
    return UserModel.fromJsonList(data);
  }

  return [];
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'dropdownSearch Demo',
      theme: ThemeData.light(),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final dropDownKey = GlobalKey<DropdownSearchState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('examples mode')),
      body: ListView(
        padding: EdgeInsets.symmetric(vertical: 12, horizontal: 8),
        children: [
          Row(
            children: [
              Expanded(
                child: DropdownSearch<String>(
                  key: dropDownKey,
                  selectedItem: "Menu",
                  items: ["Menu", "Dialog", "Modal", "BottomSheet"],
                  decoratorProps: DropDownDecoratorProps(
                    decoration: InputDecoration(
                      labelText: 'Examples for: ',
                      border: OutlineInputBorder(),
                    ),
                  ),
                  popupProps: PopupProps.menu(
                    fit: FlexFit.loose,
                    constraints: BoxConstraints(),
                  ),
                ),
              ),
              Padding(padding: EdgeInsets.only(right: 16)),
              FilledButton(
                onPressed: () {
                  switch (dropDownKey.currentState?.getSelectedItem) {
                    case 'Menu':
                      // Navigate to MenuExamplesPage
                      break;
                    case 'Modal':
                      // Navigate to ModalsExamplesPage
                      break;
                    case 'BottomSheet':
                      // Navigate to BottomSheetExamplesPage
                      break;
                    case 'Dialog':
                      // Navigate to DialogExamplesPage
                      break;
                  }
                },
                child: Text("Go"),
              )
            ],
          ),
          Padding(padding: EdgeInsets.all(8)),
          RichText(
            text: TextSpan(
              style: const TextStyle(fontSize: 14.0, color: Colors.black),
              children: [
                TextSpan(text: 'we used '),
                TextSpan(
                    text: 'fit: FlexFit.loose',
                    style: TextStyle(fontWeight: FontWeight.bold)),
                TextSpan(text: ' and '),
                TextSpan(
                    text: 'constraints: BoxConstraints() ',
                    style: TextStyle(fontWeight: FontWeight.bold)),
                TextSpan(
                    text:
                        'to fit the height of menu automatically to the length of items'),
              ],
            ),
          ),
          Padding(padding: EdgeInsets.only(top: 20)),
          Text(
            'DropdownSearch Anatomy',
            style: TextStyle(
                fontWeight: FontWeight.bold, fontStyle: FontStyle.italic),
            textAlign: TextAlign.center,
          ),
          Image.asset('assets/images/anatomy.png',
              alignment: Alignment.topCenter, height: 1024)
        ],
      ),
    );
  }
}

这个示例展示了如何创建一个包含不同模式的 DropdownSearch 组件的应用程序,并通过选择不同的模式导航到相应的页面。你可以根据自己的需求进行修改和扩展。


更多关于Flutter下拉搜索插件dropdown_search的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter下拉搜索插件dropdown_search的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用dropdown_search插件实现下拉搜索功能的代码案例。dropdown_search是一个非常流行的Flutter插件,它提供了一个带有搜索功能的下拉菜单。

首先,确保你已经在pubspec.yaml文件中添加了dropdown_search依赖:

dependencies:
  flutter:
    sdk: flutter
  dropdown_search: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Dart文件中,你可以按照以下方式使用DropdownSearch

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Dropdown Search Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 示例数据
  List<String> items = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig', 'Grape'];
  String? selectedItem;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dropdown Search Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            DropdownSearch<String>(
              mode: Mode.MENU,
              showSearchBox: true,
              label: 'Select a fruit',
              hint: 'Search a fruit...',
              items: items,
              onChanged: print,
              selectedItem: selectedItem,
              onFind: (String filter) {
                // 你可以在这里实现自定义的搜索逻辑
                return items.where((item) => item.toLowerCase().contains(filter.toLowerCase())).toList();
              },
              popupTitle: Container(
                decoration: BoxDecoration(color: Colors.blue),
                child: Center(
                  child: Text(
                    'Fruits',
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  • DropdownSearch<String>用于创建一个带有搜索功能的下拉菜单。
  • mode: Mode.MENU指定了下拉菜单的模式。
  • showSearchBox: true表示显示搜索框。
  • label是下拉菜单的标签。
  • hint是搜索框的占位符文本。
  • items是下拉菜单的数据源。
  • onChanged是一个回调函数,当用户选择一个项目时会触发。
  • selectedItem是当前选中的项目。
  • onFind是一个自定义搜索逻辑,它根据用户输入的过滤器字符串来过滤项目。
  • popupTitle用于自定义下拉菜单标题的样式。

你可以根据需要调整这些参数来实现自定义的下拉搜索功能。

回到顶部