Flutter增强型下拉选择插件dropdown_plus的使用

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

Flutter增强型下拉选择插件dropdown_plus的使用

dropdown_plus 是一个简单易用的下拉选择组件,支持表单中的搜索、键盘导航、离线数据源、远程数据源和自定义样式。它提供了丰富的配置选项,使得开发者可以轻松地集成到Flutter应用中。

Getting Started

简单文本下拉框示例

TextDropdownFormField(
    options: ["Male", "Female"],
    decoration: InputDecoration(
        border: OutlineInputBorder(),
        suffixIcon: Icon(Icons.arrow_drop_down),
        labelText: "Gender"),
    dropdownHeight: 120,
)

Screen1 Screen6

安装

pubspec.yaml 文件中添加依赖:

dependencies:
  dropdown_plus: <latest version>

可定制化示例

下面是一个更复杂的例子,展示了如何使用带有自定义项和过滤功能的 DropdownFormField 组件。

final List<Map<String, dynamic>> _roles = [
  {"name": "Super Admin", "desc": "Having full access rights", "role": 1},
  {
    "name": "Admin",
    "desc": "Having full access rights of a Organization",
    "role": 2
  },
  {
    "name": "Manager",
    "desc": "Having Management access rights of a Organization",
    "role": 3
  },
  {
    "name": "Technician",
    "desc": "Having Technician Support access rights",
    "role": 4
  },
  {
    "name": "Customer Support",
    "desc": "Having Customer Support access rights",
    "role": 5
  },
  {"name": "User", "desc": "Having End User access rights", "role": 6},
];

// ...

DropdownFormField<Map<String, dynamic>>(
    onEmptyActionPressed: () async {},
    decoration: InputDecoration(
        border: OutlineInputBorder(),
        suffixIcon: Icon(Icons.arrow_drop_down),
        labelText: "Access"),
    onSaved: (dynamic str) {},
    onChanged: (dynamic str) {},
    validator: (dynamic str) {},
    displayItemFn: (dynamic item) => Text(
          (item ?? {})['name'] ?? '',
          style: TextStyle(fontSize: 16),
        ),
    findFn: (dynamic str) async => _roles,
    selectedFn: (dynamic item1, dynamic item2) {
      if (item1 != null && item2 != null) {
        return item1['name'] == item2['name'];
      }
      return false;
    },
    filterFn: (dynamic item, str) =>
        item['name'].toLowerCase().indexOf(str.toLowerCase()) >= 0,
    dropdownItemFn: (dynamic item, int position, bool focused,
            bool selected, Function() onTap) =>
        ListTile(
          title: Text(item['name']),
          subtitle: Text(
            item['desc'] ?? '',
          ),
          tileColor:
              focused ? Color.fromARGB(20, 0, 0, 0) : Colors.transparent,
          onTap: onTap,
        ),
),

Screen4 Screen3 Screen5

Options

以下是 DropdownFormField 支持的一些常用属性:

  • autoFocus: 是否自动聚焦。
  • filterFn: 过滤函数,用于筛选显示的选项。
  • selectedFn: 比较两个项目的函数,判断是否选中。
  • findFn: 异步查找函数,返回数据列表。
  • dropdownItemFn: 自定义下拉菜单项的渲染方式。
  • displayItemFn: 自定义显示当前选中项的方式。
  • decoration: 输入框装饰。
  • dropdownColor: 下拉菜单颜色。
  • controller: 控制器,用于管理下拉框的状态。
  • onChanged: 当选项改变时触发的回调。
  • onSaved: 表单保存时触发的回调。
  • validator: 验证器,用于验证输入的有效性。
  • dropdownHeight: 下拉菜单高度。
  • searchTextStyle: 搜索文本样式。
  • emptyText: 当没有匹配项时显示的文本。
  • emptyActionText: 当没有匹配项且有操作按钮时显示的文本。
  • onEmptyActionPressed: 当点击空状态下的操作按钮时触发的回调。

示例代码

以下是一个完整的 main.dart 示例代码,展示了如何将上述组件集成到Flutter应用中。

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

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  final List<Map<String, dynamic>> _roles = [
    {"name": "Super Admin", "desc": "Having full access rights", "role": 1},
    {
      "name": "Admin",
      "desc": "Having full access rights of a Organization",
      "role": 2
    },
    {
      "name": "Manager",
      "desc": "Having Management access rights of a Organization",
      "role": 3
    },
    {
      "name": "Technician",
      "desc": "Having Technician Support access rights",
      "role": 4
    },
    {
      "name": "Customer Support",
      "desc": "Having Customer Support access rights",
      "role": 5
    },
    {"name": "User", "desc": "Having End User access rights", "role": 6},
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dropdown Plus Demo'),
      ),
      body: Container(
        padding: EdgeInsets.all(16),
        child: Column(
          children: [
            TextDropdownFormField(
              options: ["Male", "Female"],
              decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  suffixIcon: Icon(Icons.arrow_drop_down),
                  labelText: "Gender"),
              dropdownHeight: 120,
            ),
            SizedBox(
              height: 16,
            ),
            DropdownFormField<Map<String, dynamic>>(
              onEmptyActionPressed: () async {},
              decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  suffixIcon: Icon(Icons.arrow_drop_down),
                  labelText: "Access"),
              onSaved: (dynamic str) {},
              onChanged: (dynamic str) {},
              validator: (dynamic str) {},
              displayItemFn: (dynamic item) => Text(
                (item ?? {})['name'] ?? '',
                style: TextStyle(fontSize: 16),
              ),
              findFn: (dynamic str) async => _roles,
              selectedFn: (dynamic item1, dynamic item2) {
                if (item1 != null && item2 != null) {
                  return item1['name'] == item2['name'];
                }
                return false;
              },
              filterFn: (dynamic item, str) =>
                  item['name'].toLowerCase().indexOf(str.toLowerCase()) >= 0,
              dropdownItemFn: (dynamic item, int position, bool focused,
                      bool selected, Function() onTap) =>
                  ListTile(
                title: Text(item['name']),
                subtitle: Text(
                  item['desc'] ?? '',
                ),
                tileColor:
                    focused ? Color.fromARGB(20, 0, 0, 0) : Colors.transparent,
                onTap: onTap,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

通过以上内容,您可以快速上手并充分利用 dropdown_plus 插件的强大功能,为您的Flutter应用程序增添更加丰富和交互性强的用户体验。


更多关于Flutter增强型下拉选择插件dropdown_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter增强型下拉选择插件dropdown_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,dropdown_plus 是一个增强型的 Flutter 下拉选择插件,它提供了比标准 DropdownButton 更加丰富的功能和自定义选项。以下是如何在 Flutter 项目中使用 dropdown_plus 的示例代码。

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

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

然后,运行 flutter pub get 以获取依赖。

接下来,你可以在你的 Flutter 应用中使用 DropdownPlus。以下是一个完整的示例,包括如何在 StatefulWidget 中使用 DropdownPlus 并处理其选择事件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('DropdownPlus Example'),
        ),
        body: MyHomePage(),
      ),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  String? selectedValue;

  // 模拟下拉列表的选项
  final List<DropdownMenuItem<String>> dropdownItems = [
    DropdownMenuItem(value: 'Option 1', child: Text('Option 1')),
    DropdownMenuItem(value: 'Option 2', child: Text('Option 2')),
    DropdownMenuItem(value: 'Option 3', child: Text('Option 3')),
  ];

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
            'Enhanced Dropdown Selection:',
            style: TextStyle(fontSize: 20),
          ),
          SizedBox(height: 16),
          DropdownPlus<String>(
            value: selectedValue,
            hint: Text('Select an option'),
            searchEnabled: true, // 启用搜索功能
            clearButtonMode: OverlayVisibilityMode.always, // 始终显示清除按钮
            items: dropdownItems,
            onChanged: (newValue) {
              setState(() {
                selectedValue = newValue;
              });
            },
            searchInputDecoration: InputDecoration(
              border: OutlineInputBorder(),
              prefixIcon: Icon(Icons.search),
              hintText: 'Search...',
            ),
            dropdownDecoration: BoxDecoration(
              borderRadius: BorderRadius.circular(8),
              color: Colors.white,
              boxShadow: [
                BoxShadow(
                  color: Colors.grey.withOpacity(0.2),
                  spreadRadius: 5,
                  blurRadius: 7,
                  offset: Offset(0, 3), // changes position of shadow
                ),
              ],
            ),
          ),
          SizedBox(height: 24),
          Text(
            'Selected Value: $selectedValue',
            style: TextStyle(fontSize: 18),
          ),
        ],
      ),
    );
  }
}

在这个示例中:

  1. DropdownPlus 组件被用于创建一个增强型的下拉选择框。
  2. searchEnabled 属性启用了搜索功能。
  3. clearButtonMode 属性设置为 OverlayVisibilityMode.always,这样清除按钮始终可见。
  4. onChanged 回调函数用于处理用户选择的变化,并更新 selectedValue 状态。
  5. searchInputDecorationdropdownDecoration 用于自定义搜索输入框和下拉框的样式。

你可以根据需要进一步自定义 DropdownPlus 的其他属性和功能。希望这个示例能帮助你更好地理解和使用 dropdown_plus 插件。

回到顶部