Flutter自定义动画下拉选择插件animated_custom_dropdown_v2的使用

Flutter 自定义动画下拉选择插件 animated_custom_dropdown_v2 的使用

特性

animated_custom_dropdown_v2 包允许你添加可自定义的动画下拉小部件。它提供了许多属性来根据你的需求定制下拉小部件。此外,它还可以在表单小部件内使用以进行必要的验证。

  • 使用构造函数 CustomDropdown() 创建自定义下拉小部件。
  • 使用命名构造函数 CustomDropdown.search() 创建带有搜索字段的自定义下拉小部件。
  • 使用命名构造函数 CustomDropdown.searchRequest() 创建带有搜索请求字段的自定义下拉小部件。

获取开始

  1. pubspec.yaml 文件中添加最新版本的包(并运行 flutter pub get):
dependencies:
  animated_custom_dropdown_v2: 1.0.0
  1. 导入包并在你的 Flutter 应用程序中使用它:
import 'package:animated_custom_dropdown_v2/custom_dropdown.dart';

示例用法

1. 自定义下拉小部件
import 'package:animated_custom_dropdown_v2/custom_dropdown.dart';
import 'package:flutter/material.dart';

class CustomDropdownExample extends StatefulWidget {
  const CustomDropdownExample({Key? key}) : super(key: key);

  [@override](/user/override)
  State<CustomDropdownExample> createState() => _CustomDropdownExampleState();
}

class _CustomDropdownExampleState extends State<CustomDropdownExample> {
  final jobRoleCtrl = TextEditingController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return CustomDropdownV2<RoleItem>(
      hintText: 'Select job role',
      items: list,
      excludeSelected: false,
      onItemSelected: (value) {
        print('onItemSelected item $value');
        setState(() {
          selectedItem1 = value;
        });
      },
      selectedItem: selectedItem1,
    );
  }
}
2. 带有搜索字段的自定义下拉小部件
import 'package:animated_custom_dropdown_v2/custom_dropdown.dart';
import 'package:flutter/material.dart';

class CustomDropdownExample extends StatefulWidget {
  const CustomDropdownExample({Key? key}) : super(key: key);

  [@override](/user/override)
  State<CustomDropdownExample> createState() => _CustomDropdownExampleState();
}

class _CustomDropdownExampleState extends State<CustomDropdownExample> {
  final jobRoleCtrl = TextEditingController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return CustomDropdownV2<RoleItem>.search(
      hintText: 'Select job role',
      items: list,
      onItemSelected: (value) {
        setState(() {
          selectedItem2 = value;
        });
        print('onItemSelected item $value');
      },
      onSearchTextChange: (value) {
        print('onSearchTextChange $value');
      },
      selectedItem: selectedItem2,
      emptyResultWidget: const Center(
        child: Padding(
          padding: EdgeInsets.symmetric(vertical: 12.0),
          child: Text(
            'Add New Job Role',
            style: TextStyle(fontSize: 16),
          ),
        ),
      ),
      onEmptyResultClick: () {
        print('onEmptyResultClick');
      },
    );
  }
}
3. 带有搜索请求字段的自定义下拉小部件(模拟假数据)
import 'package:animated_custom_dropdown_v2/custom_dropdown.dart';
import 'package:flutter/material.dart';

class CustomDropdownExample extends StatefulWidget {
  const CustomDropdownExample({Key? key}) : super(key: key);

  [@override](/user/override)
  State<CustomDropdownExample> createState() => _CustomDropdownExampleState();
}

class _CustomDropdownExampleState extends State<CustomDropdownExample> {
  final jobRoleCtrl = TextEditingController();

  Future<List<RoleItem>> getFakeRequestData(String query) async {
    print('Future Search Query: $query');
    List<RoleItem> data = list;

    return await Future.delayed(const Duration(seconds: 1), () {
      return data.where((e) {
        return e.value.toLowerCase().contains(query.toLowerCase());
      }).toList();
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return CustomDropdownV2<RoleItem>.searchRequest(
      selectedItem: selectedItem3,
      futureRequest: getFakeRequestData,
      hintText: 'Search job role',
      // 等待 3 秒钟再开始搜索(在执行 `futureRequest` 函数之前)
      futureRequestDelay: const Duration(seconds: 3),
      onItemSelected: (value) {
        setState(() {
          selectedItem3 = value;
        });
        print('onItemSelected item $value');
      },
    );
  }
}
4. 使用表单进行验证
import 'package:animated_custom_dropdown_v2/custom_dropdown.dart';
import 'package:flutter/material.dart';

class CustomDropdownExample extends StatefulWidget {
  const CustomDropdownExample({Key? key}) : super(key: key);

  [@override](/user/override)
  State<CustomDropdownExample> createState() => _CustomDropdownExampleState();
}

class _CustomDropdownExampleState extends State<CustomDropdownExample> {
  final formKey = GlobalKey<FormState>();
  final List<RoleItem> list = ['Developer', 'Designer', 'Consultant', 'Student']
      .map((e) => RoleItem(value: e))
      .toList();
  RoleItem? selectedItem1;
  RoleItem? selectedItem2;
  RoleItem? selectedItem3;
  RoleItem? selectedItem4;

  Future<List<RoleItem>> getFakeRequestData(String query) async {
    print('Future Search Query: $query');
    List<RoleItem> data = list;

    return await Future.delayed(const Duration(seconds: 1), () {
      return data.where((e) {
        return e.value.toLowerCase().contains(query.toLowerCase());
      }).toList();
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[200],
      appBar: AppBar(
        systemOverlayStyle: SystemUiOverlayStyle.dark.copyWith(
          statusBarColor: Colors.white,
        ),
        backgroundColor: Colors.white,
        elevation: .25,
        title: const Text(
          'Custom Dropdown Example',
          style: TextStyle(color: Colors.black, fontSize: 18),
        ),
      ),
      body: ListView(
        padding: const EdgeInsets.all(16.0),
        children: [
          const Text('Job Roles Dropdown', style: _labelStyle),
          const SizedBox(height: 8),
          CustomDropdownV2<RoleItem>(
            hintText: 'Select job role',
            items: list,
            excludeSelected: false,
            onItemSelected: (value) {
              print('onItemSelected item $value');
              setState(() {
                selectedItem1 = value;
              });
            },
            selectedItem: selectedItem1,
          ),
          const SizedBox(height: 24),
          const Divider(height: 0),
          const SizedBox(height: 24),

          // 带有搜索字段的下拉菜单
          const Text('Job Roles Search Dropdown', style: _labelStyle),
          const SizedBox(height: 8),
          CustomDropdownV2<RoleItem>.search(
            hintText: 'Select job role',
            items: list,
            onItemSelected: (value) {
              setState(() {
                selectedItem2 = value;
              });
              print('onItemSelected item $value');
            },
            onSearchTextChange: (value) {
              print('onSearchTextChange $value');
            },
            selectedItem: selectedItem2,
            emptyResultWidget: const Center(
              child: Padding(
                padding: EdgeInsets.symmetric(vertical: 12.0),
                child: Text(
                  'Add New Job Role',
                  style: TextStyle(fontSize: 16),
                ),
              ),
            ),
            onEmptyResultClick: () {
              print('onEmptyResultClick');
            },
          ),
          const SizedBox(height: 24),
          const Divider(height: 0),
          const SizedBox(height: 24),

          // 带有搜索请求字段的下拉菜单(模拟假数据)
          const Text('Job Roles Search Request Dropdown', style: _labelStyle),
          const SizedBox(height: 8),
          CustomDropdownV2<RoleItem>.searchRequest(
            selectedItem: selectedItem3,
            futureRequest: getFakeRequestData,
            hintText: 'Search job role',
            // 等待 3 秒钟再开始搜索(在执行 `futureRequest` 函数之前)
            futureRequestDelay: const Duration(seconds: 3),
            onItemSelected: (value) {
              setState(() {
                selectedItem3 = value;
              });
              print('onItemSelected item $value');
            },
          ),
          const SizedBox(height: 24),
          const Divider(height: 0),
          const SizedBox(height: 24),

          // 使用表单进行验证
          Form(
            key: formKey,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text(
                  'Job Roles Dropdown with Form validation',
                  style: _labelStyle,
                ),
                const SizedBox(height: 8),
                CustomDropdownV2<RoleItem>.search(
                  selectedItem: selectedItem4,
                  hintText: 'Select job role',
                  items: list,
                  excludeSelected: false,
                  listItemBuilder: (context, result) {
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(result.displayText),
                        const Icon(Icons.person)
                      ],
                    );
                  },
                  onItemSelected: (value) {
                    setState(() {
                      selectedItem4 = value;
                    });
                    print('onItemSelected item $value');
                  },
                  onSearchTextChange: (value) {
                    print('onSearchTextChange $value');
                  },
                ),
                const SizedBox(height: 16),
                SizedBox(
                  width: double.infinity,
                  child: ElevatedButton(
                    onPressed: () {
                      if (!formKey.currentState!.validate()) {
                        return;
                      }
                    },
                    child: const Text(
                      'Submit',
                      style: TextStyle(fontWeight: FontWeight.w600),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

更多关于Flutter自定义动画下拉选择插件animated_custom_dropdown_v2的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义动画下拉选择插件animated_custom_dropdown_v2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


animated_custom_dropdown_v2 是一个 Flutter 插件,用于创建带有动画效果的自定义下拉选择框。它允许开发者自定义下拉框的样式、动画效果以及交互行为。

以下是如何在 Flutter 项目中使用 animated_custom_dropdown_v2 插件的基本步骤:

1. 添加依赖

首先,在项目的 pubspec.yaml 文件中添加 animated_custom_dropdown_v2 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  animated_custom_dropdown_v2: ^1.0.0  # 使用最新版本

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

2. 导入插件

在需要使用下拉选择框的 Dart 文件中导入插件:

import 'package:animated_custom_dropdown_v2/animated_custom_dropdown.dart';

3. 使用 AnimatedCustomDropdown 组件

在 UI 中使用 AnimatedCustomDropdown 组件来创建一个动画下拉选择框。以下是一个简单的示例:

class MyHomePage extends StatefulWidget {
  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String? selectedValue;
  final List<String> items = ['Option 1', 'Option 2', 'Option 3', 'Option 4'];

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Animated Custom Dropdown Example'),
      ),
      body: Center(
        child: AnimatedCustomDropdown(
          items: items,
          selectedItem: selectedValue,
          onChanged: (value) {
            setState(() {
              selectedValue = value;
            });
          },
          decoration: BoxDecoration(
            color: Colors.blueAccent,
            borderRadius: BorderRadius.circular(8.0),
          ),
          textStyle: TextStyle(
            color: Colors.white,
            fontSize: 16.0,
          ),
          dropdownHeight: 200.0,
          dropdownItemStyle: TextStyle(
            color: Colors.black,
            fontSize: 16.0,
          ),
          dropdownItemSelectedStyle: TextStyle(
            color: Colors.blueAccent,
            fontWeight: FontWeight.bold,
          ),
          dropdownItemPadding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
          dropdownItemDecoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(4.0),
          ),
        ),
      ),
    );
  }
}
回到顶部