flutter下拉框组件

实现下拉框效果

DropdownButton

flutter自带的组件

 Expanded(
    child: DropdownButton<
     String>(
		isExpanded:true,
        value: _therapistsId,
		items: _therapists.map((e) => DropdownMenuItem(value: e.therapistId,child: Text(e.therapistName))).toList(),
        onChanged: (e) {
           if (e is String) {
           	setState(() {
                _therapistsId = e;
               ///...
            });
       }
})),

插件 dropdown_search

单选

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

class DropDownSingle extends StatelessWidget {
  const DropDownSingle(
      {super.key,
      required this.options,
      required this.value,
      required this.onChanged});
  final List<DropDownType> options;
  final String value;
  final ValueChanged<String> onChanged;

  
  Widget build(BuildContext context) {
    return DropdownSearch(
      items: options.map((e) => e.k).toList(),
      selectedItem: options.where((f) => f.v == value).toList().isNotEmpty
          ? options.where((f) => f.v == value).toList()[0].k
          : '',
      onChanged: (value) {
        var list = options.where((f) => f.k == value).toList();
        if (list.isNotEmpty) {
          onChanged(list[0].v);
        }
      },
       popupProps: PopupProps.menu(
          constraints: BoxConstraints(
              maxHeight: options.length < 5 ? options.length * 58 : 5 * 58)),/// 下拉框的长度修改
    );
  }
}

类型

class DropDownType {
  DropDownType({
    required this.k,
    required this.v,
  });

  final String k;

  final String v;
}

使用:

 Expanded(
    child: DropDownSingle(options: _therapists.map((e) => DropDownType(k: e.therapistName,v: e.therapistId)).toList(),
    value:_therapistsId ??"",
    onChanged: (e) {
      setState(() {
         _therapistsId = e;
        ///
   });
   }),
)

多选:

import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:rehab_therapist/components/form_widget/drop_down_type.dart';

class DropDownMulti extends StatelessWidget {
  const DropDownMulti(
      {super.key,
      required this.options,
      required this.value,
      required this.onChanged});
  final List<DropDownType> options;
  final List<String> value;
  final ValueChanged<List<String>> onChanged;

  
  Widget build(BuildContext context) {
    return DropdownSearch.multiSelection(
      clearButtonProps: const ClearButtonProps(isVisible: true),
      items: options.map((e) => e.k).toList(),
      selectedItems: options
          .where((f) => value.contains(f.v))
          .toList()
          .map((e) => e.k)
          .toList(),
      onChanged: (value) {
        var list = options
            .where((f) => value.contains(f.k))
            .toList()
            .map((e) => e.v)
            .toList();
        onChanged(list);
      },
    );
  }
}

上述使用方法与单选下拉类似

实现多选下拉框

组件:

/// @description: 多选下拉组件

import 'package:flutter/material.dart';

class SelectOption {
  SelectOption({required this.value, required this.label});
  String label;
  dynamic value;
}

class MultiSelectDropdownButton extends StatefulWidget {
  final String labelText;
  final List<SelectOption> items;
  final List<dynamic> selectedItems;
  final ValueChanged<List<dynamic>> onChanged;

  // ignore: prefer_const_constructors_in_immutables
  MultiSelectDropdownButton({
    super.key,
    required this.labelText,
    required this.items,
    required this.selectedItems,
    required this.onChanged,
  });

  
  // ignore: library_private_types_in_public_api
  _MultiSelectDropdownButtonState createState() =>
      _MultiSelectDropdownButtonState();
}

class _MultiSelectDropdownButtonState extends State<MultiSelectDropdownButton> {
  final List<dynamic> _selectedItems = [];
  final List<String> _selectedLables = [];

  
  void initState() {
    super.initState();
    _selectedItems.addAll(widget.selectedItems);
    for (var item in _selectedItems) {
      for (var e in widget.items) {
        if (e.value == item) _selectedLables.add(e.label);
      }
    }
  }

  
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(widget.labelText),
        PopupMenuButton(
          itemBuilder: (BuildContext context) {
            return widget.items.map((SelectOption e) {
              return CheckedPopupMenuItem(
                value: e.value,
                checked: _selectedItems.contains(e.value),
                child: Text(e.label),
              );
            }).toList();
          },
          onSelected: (item) {
            setState(() {
              if (_selectedItems.contains(item)) {
                _selectedItems.remove(item);
                for (var e in widget.items) {
                  if (e.value == item) _selectedLables.remove(e.label);
                }
              } else {
                _selectedItems.add(item);
                _selectedItems.sort();
                for (var e in widget.items) {
                  if (e.value == item) {
                    _selectedLables.insert(
                        _selectedItems.indexOf(item), e.label);
                  }
                }
              }
              widget.onChanged(_selectedItems);
            });
          },
          child: Container(
            alignment: Alignment.centerLeft,
            decoration: BoxDecoration(
              border: Border.all(),
              borderRadius: BorderRadius.circular(4.0),
            ),
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              child: Text(_selectedLables.join(', ')),
            ),
          ),
        ),
      ],
    );
  }
}

使用:

 									Expanded(
                                              flex: 1,
                                              child: SizedBox(
                                                height: 30,
                                                child: ListView(
                                                  scrollDirection:
                                                      Axis.horizontal,
                                                  children: [
                                                    MultiSelectDropdownButton(
                                                        labelText: '',
                                                        items: [
                                                          SelectOption(
                                                              value: "肩",
                                                              label: "肩"),
                                                          SelectOption(
                                                              value: "肘",
                                                              label: "肘"),
                                                          SelectOption(
                                                              value: "腕",
                                                              label: "腕"),
                                                          SelectOption(
                                                              value: "髋",
                                                              label: "髋"),
                                                          SelectOption(
                                                              value: "膝",
                                                              label: "膝"),
                                                          SelectOption(
                                                              value: "踝",
                                                              label: "踝"),
                                                          SelectOption(
                                                              value: "脊柱",
                                                              label: "脊柱"),
                                                          SelectOption(
                                                              value: "其他",
                                                              label: "其他"),
                                                        ],
                                                        selectedItems:
                                                            _injureBase,
                                                        onChanged:
                                                            (List<dynamic>
                                                                value) {
                                                          Future.delayed(
                                                              const Duration(
                                                                  milliseconds:
                                                                      1), () {
                                                            FocusScope.of(
                                                                    context)
                                                                .unfocus();
                                                          });
                                                          setState(() {
                                                            _injureBase = value;
                                                          });
                                                          if (value
                                                              .contains("其他")) {
                                                            setState(() {
                                                              _showinjureOthersPart =
                                                                  true;
                                                            });
                                                          } else {
                                                            setState(() {
                                                              _showinjureOthersPart =
                                                                  false;
                                                            });
                                                            _userTypeController
                                                                .text = "";
                                                          }
                                                        })
                                                  ],
                                                ),
                                              )),

如果多选下拉框要修改“ok”,则如下:

import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:rehab_therapist/components/form_widget/drop_down_type.dart';

class DropDownMulti extends StatelessWidget {
  const DropDownMulti(
      {super.key,
      required this.options,
      required this.value,
      required this.onChanged});
  final List<DropDownType> options;
  final List<String> value;
  final ValueChanged<List<String>> onChanged;

  
  Widget build(BuildContext context) {
    final popupCustomValidationKey = GlobalKey<DropdownSearchState<dynamic>>();
    return DropdownSearch.multiSelection(
      key: popupCustomValidationKey,
      clearButtonProps: const ClearButtonProps(isVisible: true),
      items: options.map((e) => e.k).toList(),
      selectedItems: options
          .where((f) => value.contains(f.v))
          .toList()
          .map((e) => e.k)
          .toList(),
      onChanged: (value) {
        var list = options
            .where((f) => value.contains(f.k))
            .toList()
            .map((e) => e.v)
            .toList();
        onChanged(list);
      },
      popupProps: PopupPropsMultiSelection.menu(
          validationWidgetBuilder: (context, selectedItems) => Container(
                padding: const EdgeInsets.only(right: 10),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    ElevatedButton(
                        onPressed: () {
                          popupCustomValidationKey.currentState
                              ?.popupValidate(selectedItems);
                        },
                        child: const Text("确定"))
                  ],
                ),
              )),
    );
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter中,可以使用DropdownButtonFormField或自定义的SelectWidget来创建下拉菜单。引用\[1\]中的代码演示了如何使用自定义的SelectWidget来创建下拉菜单。在SelectWidget中,通过传入一个MenuItem列表来定义下拉菜单的选项,然后通过value属性来指定当前选中的值,通过valueChanged回调函数来处理选中值的改变。 引用\[2\]中的代码演示了如何使用DropdownButtonFormField来创建下拉菜单。在DropdownButtonFormField中,通过value属性来指定当前选中的值,通过items属性来定义下拉菜单的选项,通过onChanged回调函数来处理选中值的改变。 如果你想创建一个通用的菜单项类,可以参考引用\[3\]中的代码。MenuItem类包含了显示的文本label、选中的值value和是否选中的checked属性,可以根据需要进行自定义。 所以,根据你的问题,你可以使用自定义的SelectWidget或者DropdownButtonFormField来创建Flutter下拉框。 #### 引用[.reference_title] - *1* *3* [flutter实现下拉菜单组件——基于PopupMenuButton](https://blog.csdn.net/weixin_39033300/article/details/130456842)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [flutter实现下拉框功能——基于DropdownButtonFormField](https://blog.csdn.net/weixin_39033300/article/details/130291685)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值