Flutter 底部弹窗如何实现多项选择
作者:岛上码农 发布时间:2023-06-24 17:08:17
多选和单选的不同之处
单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理。但到多选的时候,需要知道当前选中的选项,有选项被点击的时候需要存储下来,当再次被点击的时候要清空这个选项,同时界面还需要同步更新,因此就涉及到状态管理了。
实现方式
在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,
),
),
]),
);
});
},
);
}
总结
本篇介绍了底部弹窗实现多选的方式,其中实现的方式还可以有很多种,例如直接在自定义组件中使用有状态组件。这里介绍的方法可以作为一个参考,通过动态构建有状态组件能够简单快速地实现底部弹窗的多选功能。
来源:https://juejin.cn/post/6972106616925585444


猜你喜欢
- 如下所示:for (int i= 0; i<= 1084; i++) {if (String.valueOf(i+1).length(
- 这篇文章主要介绍了java property配置文件管理工具框架过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 本文实例为大家分享了Android保存QQ密码功能的具体代码,供大家参考,具体内容如下技术要点:使用文件储存的方式保存数据实现步骤:①用户交
- 一、Shiro整体概述1.简介Apache Shiro是Java的一个安全框架,功能强大,使用简单,Shiro为开发人员提供了一个直观而全面
- 一、题目描述题目实现:网络资源的断点续传功能。二、解题思路获取要下载的资源网址显示网络资源的大小上次读取到的字节位置以及未读取的字节数输入下
- 本文实例为大家分享了Android使用GridView实现横向滚动效果的具体代码,供大家参考,具体内容如下第一次做横向滑动,看了一些列子,基
- 本文实例为大家分享了WPF实现半圆形导航菜单的具体代码,供大家参考,具体内容如下实现效果如下:思路:扇形自定义控件组合成半圆型菜单,再通过c
- 正文:相关术语翻译说明:Mark,标记;Sweep,清除;Compact,整理; 也有人翻译为压缩,译者认为GC时不存在压缩这回事。Copy
- 当我们需要制作动态炫酷科技感很强的UI时,美术一般会给我们提供一些序列图,这时候我们只需在程序里实现序列动画。一.动画机unity自带的帧动
- 背景Java8的stream接口极大地减少了for循环写法的复杂性,stream提供了map/reduce/collect等一系列聚合接口,
- 一、SpringMVC使用1.工程创建创建maven工程。添加java、resources目录。引入Spring-webmvc 依赖。<
- 一、 序列化和反序列化概念Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是
- C语言数据结构之二叉树的非递归后序遍历算法前言:前序、中序、后序的非递归遍历中,要数后序最为麻烦,如果只在栈中保留指向结点的指针,那是不够的
- 首先,将json串转为一个JObject对象:JObject jo = (JObject)JsonConvert.DeserializeOb
- springboottest测试依赖和使用<dependency> <groupId>or
- idea工具使用 Java Exception Breakpoint 添加异常断点,在IDE里,新建一个断点,类型是Java Excepti
- @GetMapping注解携带参数方式今天突然发现,当我们根据id查询用户信息时,如果不想通过localhost:8080//findOne
- 桥接模式概述桥接模式(Bridge Pattern)也称为桥梁模式、接口(Interfce)模式或柄体(Handle and Body)模式
- 本文实例讲述了Android编程开发ScrollView中ViewPager无法正常滑动问题解决方法。分享给大家供大家参考,具体如下:这里主
- 本文主要介绍了WPF中常用的鼠标事件、键盘事件以及注意事项,同时使用一个案例讲解了拓展事件。除此之外,本文还讲述如何用行为(Behavior