flutter插件开发,自定义下拉组件,可自定义UI,只提供框架
还有一个停产的版本 失误造成的 名字叫flutter_cunstimize_dropdown,那个不维护了,尴尬了命名错了
创建命令
dartflutter create --org com.example --template=plugin --platforms=android,ios -a java -i objc flutter_custom_dropdown
本组件由Github作者best-flutter插件flutter_dropdown_menu更改而来,由于更新问题,以及使用上不满足业务问题自己修改了相关bug做了更新迭代,所以重新集成为新插件
DefaultDropdownMenuController
功能:包裹页面提供默认Controller
功能参数 | 是否必要 | 类型 | 备注 |
---|---|---|---|
onSelected | true | bool | 选中时,触发controller.selected时会回调此方法 |
child | true | widget | 包裹内容 |
DropdownHeader
功能:下拉头部模块
功能参数 | 是否必要 | 类型 | 备注 |
---|---|---|---|
isSideline | false | bool | 是否需要分割线 |
onTap | false | func | 触发头部回调,内部自动提供,自定义头部事件需自定义 |
titles | true | List | 头部显示title列表 |
selectIsChangingColor | false | bool | 选中是否更改回显title字段可specialModules联合使用 |
specialModules | false | List | 选中是否只改变title颜色不更改title文字,此功能selectIsChangingColor必须为true,权重大于selectIsChangingColor功能 |
DropdownMenu
功能:悬停筛选模块
功能参数 | 是否必要 | 类型 | 备注 |
---|---|---|---|
menus | true | List | list长度必须与titles长度一致 |
packUpHeight | false | double | 收起长度不够时可自行添加 |
hideDuration | false | Duration | 收起时自定义时长 |
showDuration | false | Duration | 展开时自定义时长 |
showCurve | false | Curve | 自定义动画 |
hideCurve | false | Curve | 自定义动画 |
blur | false | double | 蒙层透明值 |
onHide | false | VoidCallback | 蒙层触发操作回调 |
switchStyle | false | DropdownMenuShowHideSwitchStyle | 菜单样式 |
maxMenuHeight | false | double | 最大高度,未提供自动计算时,需要指定最大高度 |
DropdownMenuBuilder
功能:menus内容
功能参数 | 是否必要 | 类型 | 备注 |
---|---|---|---|
builder | true | WidgetBuilder | 下拉内容 |
screenHeight | false | double | 最大高度,默认屏幕高度,自动计算时必须填写 |
draughtHeight | true | double | 内容高度, |
bottomSpacingHeight | false | double | 距离屏幕底部高度,自动计算时必须填写 |
单选图片功能详解
功能 | 实现功能 | 内容 |
---|---|---|
交易类型 | 单选选中,不提供title变色,不提供title更改 | 条件:剔除元数据title字段 |
范围 | 单选选中,提供title变色,不提供title更改 | 条件:添加元数据title字段,将header下标放入specialModules,开启selectIsChangingColor |
排序 | 单选选中,提供title变色,提供title更改 | 条件:添加元数据title字段,禁止将header下标放入specialModules,开启selectIsChangingColor |
DropdownListMenu
多功能tempalte,单选+多选+自定义按钮+自定义输入
功能参数 | 是否必要 | 类型 | 备注 |
---|---|---|---|
selectedIndex | false | Object | 默认选中 |
isOperatingButton | false | bool | 是否需要按钮 |
isCustomInput | false | bool | 是否需要自定义输入 |
customInput | false | CustomInputClass | 定义自定义输入回显值的key与输入框HintText |
keyWords | true | String | 数据是否重复判断依据 |
valueKey | false | String | 当元数据没有title字段时,显示内容的key需要传入|也可以自定义itemBuilder内容 |
isMultiple | false | bool | 是否多选 |
data | true | List | 元数据内容 |
itemBuilder | true | MenuItemBuilder | 展示item布局,可自定义 |
功能实现 | 实现功能 | 内容 |
---|---|---|
交易金额 | 多选+自定义输入+自定义按钮 | 看图 |
范围 | 多选 | 看图 |
排序 | 多选+自定义按钮 | 看图 |
DropdownMenuCustomize
功能:自定义下拉内容
功能参数 | 是否必要 | 类型 | 备注 |
---|---|---|---|
data | false | List | 传入内容 |
itemBuilder | true | BlankMenuItemBuilder | 内容整个布局 |
额外使用功能:
flutterDropdownMenuController controller; 控制显示关闭,可以配合WillPopScope返回时监听是否关闭并进行关闭之后再进行页面退出 onWillPop: () async{ if(controller == null || controller.event == DropdownEvent.HIDE){ Navigator.pop(context); } controller.hide(); return; } GlobalKey _globalKey;获取context,必须有变化的组件下,绝对布局或者滚动,需要获取绝对布局的context ScrollController scrollController;控制动画的
controller.assignment({'title': '更多---'}, menuIndex);///自定义内容时没有用到select传输数据可以由次方法重新更改title
贴段代码吧
dart/// TODO : 单选实例 /// @param /// @return /// @author 丁平 /// created at 2021/1/12 11:06 /// class MotionlessScreeningFilter extends StatefulWidget { @override _MotionlessScreeningFilterState createState() => _MotionlessScreeningFilterState(); } class _MotionlessScreeningFilterState extends State<MotionlessScreeningFilter> { String value1; String value2; String value3; @override Widget build(BuildContext context) { return Container( child:DefaultDropdownMenuController( onSelected: ({int menuIndex, dynamic data}) { print("int menuIndex, dynamic data = $menuIndex,$data"); if(menuIndex == 0){ value1 = '选中下标$menuIndex,\n选中内容$data'; } if(menuIndex == 1){ value2 = '选中下标$menuIndex,\n选中内容$data'; } if(menuIndex == 2){ value3 = '选中下标$menuIndex,\n选中内容$data'; } setState(() {}); }, child: Stack( children: [ Column( children: [ Container( color: Colors.white, child: buildDropdownHeader() ), Expanded( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('交易类型选中 : ${value1??''}'), const SizedBox(height: 10.0,), Text('范围选中 : ${value2??''}'), const SizedBox(height: 10.0,), Text('排序选中 : ${value3??''}'), ], ), ) ), Container( alignment: Alignment.centerLeft, color:const Color(0XFF00CCA9), child: Text( '交易类型筛选:单选,不提供选中头部回显,在元数据中剔除title字段即可 \n\n范围筛选:单选,不提供选中头部回显,但是提供选中头部颜色更改,使用specialModules属性标注,\n\n排序类型筛选:单选,提供选中内容头部回显不剔除title字段,设置selectIsChangingColor属性', style: TextStyle( color: Colors.white ), ), ) ], ), Padding( padding: const EdgeInsets.only(top: 40), child: buildDropdownMenu(context)) ], ), ) ); } DropdownHeader buildDropdownHeader({DropdownMenuHeadTapCallback onTap}) { return DropdownHeader( isSideline : false, onTap: onTap, titles: ['交易类型','范围','排序'], selectIsChangingColor: true, specialModules: [1] ,///特殊模块,选中数据只亮起,不需要更改头部title,下标为1 ); } DropdownMenu buildDropdownMenu(BuildContext context) { return new DropdownMenu( menus: [ DropdownMenuBuilder( builder : (BuildContext context) { return DropdownListMenu( selectedIndex: FilterData.housingTypes[0], isOperatingButton : false, keyWords : "key", data: FilterData.housingTypes, valueKey: 'value', itemBuilder: buildCheckItem, ); }, screenHeight : MediaQuery.of(context).size.height, draughtHeight : 60 * 2.5, bottomSpacingHeight : 168.0 ), DropdownMenuBuilder( builder : (BuildContext context) { return DropdownListMenu( selectedIndex: FilterData.ranges[0], isOperatingButton : false, keyWords : "key", data: FilterData.ranges, itemBuilder: buildCheckItem, ); }, screenHeight : MediaQuery.of(context).size.height, draughtHeight : 60 * 2.5, bottomSpacingHeight : 168.0 ), DropdownMenuBuilder( builder : (BuildContext context) { return DropdownListMenu( selectedIndex: FilterData.sort[0], isOperatingButton : false, keyWords : "key", data: FilterData.sort, itemBuilder: buildCheckItem, ); }, screenHeight : MediaQuery.of(context).size.height, draughtHeight : 60 * 6.66, bottomSpacingHeight : 168.0 + 50.0 ), ] ); } }
本文作者:还是夸张一点
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!