Flutter自定义下拉选择框dropDownMenu

利用PopupMenuButtonPopupMenuItem写了个下拉选择框,之所以不采用系统的,是因为自定义的更能适配项目需求,话不多说,直接看效果

请添加图片描述

下面直接贴出代码、代码中注释写的都很清楚,使用起来应该很方便,如果有任何问题,欢迎下方留言…
import 'package:flutter/material.dart';class DropMenuWidget extends StatefulWidget {final List<Map<String, dynamic>> data; //数据final Function(String value) selectCallBack; //选中之后回调函数final String? selectedValue; //默认选中的值final Widget? leading; //前面的widget,一般是titlefinal Widget trailing; //尾部widget,一般是自定义图片final Color? textColor;final Offset offset; //下拉框向下偏移量--手动调整间距---防止下拉框遮盖住显示的widgetfinal TextStyle normalTextStyle; //下拉框的文字样式final TextStyle selectTextStyle; //下拉框选中的文字样式final double maxHeight; //下拉框的最大高度final double maxWidth; //下拉框的最大宽度final Color? backGroundColor; //下拉框背景颜色final bool animation; //是否显示动画---尾部图片动画final int duration; //动画时长const DropMenuWidget({super.key,this.leading,required this.data,required this.selectCallBack,this.selectedValue,this.trailing = const Icon(Icons.arrow_drop_down),this.textColor = Colors.white,this.offset = const Offset(0, 30),this.normalTextStyle = const TextStyle(color: Colors.white,fontSize: 12.0,),this.selectTextStyle = const TextStyle(color: Colors.red,fontSize: 12.0,),this.maxHeight = 200.0,this.maxWidth = 200.0,this.backGroundColor = const Color.fromRGBO(28, 34, 47, 1),this.animation = true,this.duration = 200,});@overrideState<DropMenuWidget> createState() => _DropMenuWidgetState();
}class _DropMenuWidgetState extends State<DropMenuWidget>with SingleTickerProviderStateMixin {late AnimationController _animationController;late Animation<double> _animation;String _selectedLabel = '';String _currentValue = '';// 是否展开下拉按钮bool _isExpand = false;@overridevoid initState() {super.initState();_currentValue = widget.selectedValue ?? '';if (widget.animation) {_animationController = AnimationController(vsync: this,duration: Duration(milliseconds: widget.duration),);_animation = Tween(begin: 0.0, end: 0.5).animate(CurvedAnimation(parent: _animationController,curve: Curves.easeInOut,),);}}@overridevoid dispose() {_animationController.dispose();super.dispose();}_toggleExpand() {setState(() {if (_isExpand) {_animationController.forward();} else {_animationController.reverse();}});}//根据传值处理显示的文字_initLabel() {if (_currentValue.isNotEmpty) {_selectedLabel = widget.data.firstWhere((item) => item['value'] == _currentValue)['label'];} else if (widget.data.isNotEmpty) {// 没值默认取第一个_selectedLabel = widget.data[0]['label'];_currentValue = widget.data[0]['value'];}}@overrideWidget build(BuildContext context) {_initLabel();return PopupMenuButton(constraints: BoxConstraints(maxHeight: widget.maxHeight,maxWidth: widget.maxWidth,),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.0),),offset: widget.offset,color: widget.backGroundColor,onOpened: () {if (widget.animation) {setState(() {_isExpand = true;_toggleExpand();});}},onCanceled: () {if (widget.animation) {setState(() {_isExpand = false;_toggleExpand();});}},child: Container(alignment: Alignment.centerLeft,height: 40,child: FittedBox(//使用FittedBox是为了适配当字符串长度超过指定宽度的时候,会让字体自动缩小child: Row(children: [if (widget.leading != null) widget.leading!,Text(_selectedLabel,style: TextStyle(color: widget.textColor,fontSize: 14.0,),),if (widget.animation)AnimatedBuilder(animation: _animation,builder: (context, child) {return Transform.rotate(angle: _animation.value * 2.0 * 3.14, // 180度对应的弧度值child: widget.trailing,);},),if (!widget.animation) widget.trailing,],),),),itemBuilder: (context) {return widget.data.map((e) {return PopupMenuItem(child: Text(e['label'],style: e['value'] == _currentValue? widget.selectTextStyle: widget.normalTextStyle,),onTap: () {setState(() {_currentValue = e['value'];widget.selectCallBack(e['value']);});},);}).toList();},);}
}
使用
Container(color: Colors.grey,width: 130,alignment: Alignment.centerLeft,child: DropMenuWidget(leading: const Padding(padding: EdgeInsets.only(right: 10),child: Text('当前选中:'),),data: const [{'label': '华为', 'value': '1'},{'label': '小米', 'value': '2'},{'label': 'Apple', 'value': '3'},{'label': '乔布斯', 'value': '4'},{'label': '啦啦啦啦啦', 'value': '5'},{'label': '呵呵', 'value': '7'},{'label': '乐呵乐呵', 'value': '7'},],selectCallBack: (value) {print('选中的value是:$value');},offset: const Offset(0, 40),selectedValue: '3', //默认选中第三个),)

简书地址如果喜欢,希望给个star😄😄

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/264690.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Diffusion Models: A Comprehensive Survey of Methods and Applications

摘要 扩散模型作为一个强大的新的深度生成模型系列出现&#xff0c;在许多应用中具有破纪录的性能&#xff0c;包括图像合成、视频生成和分子设计。在这项调查中&#xff0c;我们对迅速扩大的扩散模型的工作进行了概述&#xff0c;将研究分为三个关键领域&#xff1a;有效采样…

[b01lers2020]Life on Mars 一个接口的sql schema.schemate表

这里还是很简单的 啥也没有 然后抓包看看 发现传递参数 直接尝试sql 然后如果正确就会返回值 否则 返回1 chryse_planitia union select database(),version() 发现回显 直接开始注入 chryse_planitia union select database(),version()chryse_planitia union select data…

LeetCode5.最长回文子串

昨天和之前打比赛的队友聊天&#xff0c;他说他面百度面到这道算法题&#xff0c;然后他用暴力法解的&#xff0c;面试官让他优化他没优化出来&#xff0c;这道题我之前没写过&#xff0c;我就想看看我能不能用效率高一点的方法把它做出来&#xff0c;我一开始就在想用递归或者…

使用dockerfile 构建自己的nacos-mysql

前言 在部署nacos的时候触发的脑袋灵光一闪&#xff0c;每次部署nacos都要部署下mysql服务器&#xff0c;然后导入sql语句&#xff0c;配置nacos配置文件&#xff0c;那有没有简单的方法实现一键部署nacos和nacos-mysql 呢? 答案是肯定&#xff01;如下目录图&#xff1a; …

C++笔记之Delegate和委托构造(Delegating constructor)

C笔记之Delegate和委托构造辨析 code review! —— 杭州 2023-12-10 文章目录 C笔记之Delegate和委托构造辨析0.有道词典&#xff1a;英语发音1.ChatGPT&#xff1a;delegate概念详解2.Delegate和“将可调用对象作为函数参数”是不是一回事&#xff1f;3.C的Delegate示例4.…

二维码智慧门牌管理系统升级解决方案:数字化房产管理

文章目录 前言一、全面信息记录&#xff1a;提升管理效率二、多种优势功能&#xff1a;系统化管理与无缝对接三、安全隐私保护&#xff1a;数据安全的重要性四、总结&#xff1a;提升管理效率与居住体验 前言 科技驱动房产管理 随着科技的飞速发展&#xff0c;房产管理领域也面…

力扣每日一题day33[111. 二叉树的最小深度]

给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;2示例 2&#xff1a; 输入…

Day56力扣打卡

打卡记录 数对统计&#xff08;DP状态压缩&#xff09; 参考文献 #include <bits/stdc.h>using namespace std;void solve(){int n;cin >> n;map<int, int> mapp;vector<int> a(n);for (auto& x : a){cin >> x;mapp[x] ;}vector<array&…

探索HarmonyOS_开发软件安装

随着华为推出HarmonyOS NEXT 宣布将要全面启用鸿蒙原声应用&#xff0c;不在兼容安卓应用&#xff0c; 现在开始探索鸿蒙原生应用的开发。 HarmonyOS应用开发官网 - 华为HarmonyOS打造全场景新服务 鸿蒙官网 开发软件肯定要从这里下载 第一个为微软系统(windows)&#xff0c;第…

深度学习 | Pytorch深度学习实践 (Chapter 12 Basic RNN)

十二、Basic RNN —— 实际上就是对线性层的复用 使用RNN最重要的两点&#xff1a; 了解序列数据的维度&#xff1b;循环过程所用的权重共享机制&#xff1b; 一般就是自己写个循环&#xff0c;权重层重复用就行了&#xff1b; 回顾&#xff1a;-----------------------------…

Spring Cloud gateway - CircuitBreaker GatewayFilte

前面学习Spring cloud gateway的时候&#xff0c;做测试的过程中我们发现&#xff0c;Spring Cloud Gateway不需要做多少配置就可以使用Spring Cloud LoadBalance的功能&#xff0c;比如&#xff1a; spring:application:name: spring-gatewaycloud:gateway:routes:- id: path…

DSP外部中断笔记

中断原理 三部分 注意 &#xff0c;外部中断使能&#xff0c;PIE使能&#xff0c;CPU中断使能 外部中断有7个&#xff0c;PIE有12组&#xff0c;一个组有8个中断复用。只有一个CPU中断可执行。 外部中断原理 1、外部中断概述 外部中断结构图 外部中断XINT1对应的是0到31GPIO…