Flutter多项选择弹窗实现详解
在Flutter 底部弹窗详解一篇中介绍了底部弹窗的实现。发出后有在琢磨如何实现多选,这也是很常用的一个功能。本篇介绍实现多选的思路和实现方式。
多选和单选的不同之处
单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理。但到多选的时候,需要知道当前选中的选项,有选项被点击的时候需要存储下来,当再次被点击的时候要清空这个选项,同时界面还需要同步更新,因此就涉及到状态管理了。
实现方式
在Flutter 中提供了一个 StatefulBuilder
的类,提供了一个 builder
方法构建有状态组件,并且提供了状态更新方法,因此在里面完成状态管理。
StatefulBuilder(builder: (context1, setState) { return Widget; } )
在这个 builder
方法中,setState
其实就是对应状态组件的setState
对应的方法,这个 state 就是用于控制 StatefulBuilder
生成的组件的状态的。这种方式有点类似于 React
的 useState
的钩子函数用法。
界面变更
首先底部弹窗的头部组件要更换,需要增加确认按钮,将构建该组件的方法抽离出来如下所示:
Widget _getModalSheetHeaderWithConfirm(String title, {Function onCancel, Function onConfirm}) { return SizedBox( height: 50, child: Row( children: [ IconButton( icon: Icon(Icons.close), onPressed: () { onCancel(); }, ), Expanded( child: Center( child: Text( title, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0), ), ), ), IconButton( icon: Icon( Icons.check, color: Colors.blue, ), onPressed: () { onConfirm(); }), ], ), ); }
通过这个方法可以通过外部参数传入标题,取消响应事件回调和确认事件回调,通用性更强。
其次是选项需要有图标标记,选中时显示为勾选框,未选中时是空白框,这需要通过状态数据来控制。这里我们使用了 Set
类型,保证选中的数据集是不重复的。在点击选项时,如果选项对应数组的下标在 Set
内,则从中移出,表示取消选择;如果不在 Set
内,则加入其中,表示选中。这个过程需要包在 state
里,以更新界面。通过列表元素当前的下标是否在 Set
内,如果在则显示为选中,不在则显示未选中。
最后是确认事件的回调,确认后将 Set
的元素转换为数组返回,然后供上级业务使用选中的下标数组判断选择了那些数据。
代码实现
关键代码实现如下,重点关注一下StatefulBuilder
的使用和利用 Set
这一数据类型对应的选择和取消选择的操作业务逻辑。
Future<List<int>> _showMultiChoiceModalBottomSheet( BuildContext context, List<String> options) async { Set<int> selected = Set<int>(); return showModalBottomSheet<List<int>>( backgroundColor: Colors.transparent, isScrollControlled: true, context: context, builder: (BuildContext context) { return StatefulBuilder(builder: (context1, setState) { return Container( clipBehavior: Clip.antiAlias, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: const Radius.circular(20.0), topRight: const Radius.circular(20.0), ), ), height: MediaQuery.of(context).size.height / 2.0, child: Column(children: [ _getModalSheetHeaderWithConfirm('多选底部弹窗', onCancel: () { Navigator.of(context).pop(); }, onConfirm: () { Navigator.of(context).pop(selected.toList()); }, ), Divider(height: 1.0), Expanded( child: ListView.builder( itemBuilder: (BuildContext context, int index) { return ListTile( trailing: Icon( selected.contains(index) ? Icons.check_box : Icons.check_box_outline_blank, color: Theme.of(context).primaryColor), title: Text(options[index]), onTap: () { setState(() { if (selected.contains(index)) { selected.remove(index); } else { selected.add(index); } }); }, ); }, itemCount: options.length, ), ), ]), ); }); }, ); }
总结
本篇介绍了底部弹窗实现多选的方式,其中实现的方式还可以有很多种,例如直接在自定义组件中使用有状态组件。这里介绍的方法可以作为一个参考,通过动态构建有状态组件能够简单快速地实现底部弹窗的多选功能。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Compose for Desktop 鼠标事件示例demo
这篇文章主要为大家介绍了Compose for Desktop 鼠标事件示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-03-03Android UI设计与开发之仿人人网V5.9.2最新版引导界面
这篇文章主要为大家详细介绍了Android UI设计与开发之仿人人网V5.9.2最新版引导界面,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-08-08Notification与NotificationManager详细介绍
在Android系统中,发一个状态栏通知还是很方便的。下面我们就来看一下,怎么发送状态栏通知,状态栏通知又有哪些参数可以设置2012-11-11Android提高之自定义Menu(TabMenu)实现方法
这篇文章主要介绍了Android自定义Menu(TabMenu)实现方法,是非常实用的功能,需要的朋友可以参考下2014-08-08详解 Kotlin Reference Basic Types, String, Array and Imports
这篇文章主要介绍了详解 Kotlin Reference Basic Types, String, Array and Imports的相关资料,需要的朋友可以参考下2017-06-06Android编程实现拦截短信并屏蔽系统Notification的方法
这篇文章主要介绍了Android编程实现拦截短信并屏蔽系统Notification的方法,较为详细的分析了Android短信与Notification的原理及对应的设置取消技巧,需要的朋友可以参考下2015-12-12
最新评论