Flutter多项选择弹窗实现详解

目录
  • 多选和单选的不同之处
  • 实现方式
  • 界面变更
  • 代码实现
  • 总结

在Flutter 底部弹窗详解一篇中介绍了底部弹窗的实现。发出后有在琢磨如何实现多选,这也是很常用的一个功能。本篇介绍实现多选的思路和实现方式。

多选和单选的不同之处

单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理。但到多选的时候,需要知道当前选中的选项,有选项被点击的时候需要存储下来,当再次被点击的时候要清空这个选项,同时界面还需要同步更新,因此就涉及到状态管理了。

实现方式

在Flutter 中提供了一个 StatefulBuilder 的类,提供了一个 builder方法构建有状态组件,并且提供了状态更新方法,因此在里面完成状态管理。

StatefulBuilder(builder: (context1, setState) {
  	return Widget;
	}
)

在这个 builder 方法中,setState 其实就是对应状态组件的setState 对应的方法,这个 state 就是用于控制 StatefulBuilder 生成的组件的状态的。这种方式有点类似于 ReactuseState 的钩子函数用法。

界面变更

首先底部弹窗的头部组件要更换,需要增加确认按钮,将构建该组件的方法抽离出来如下所示:

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,
              ),
            ),
          ]),
        );
      });
    },
  );
}

总结

本篇介绍了底部弹窗实现多选的方式,其中实现的方式还可以有很多种,例如直接在自定义组件中使用有状态组件。这里介绍的方法可以作为一个参考,通过动态构建有状态组件能够简单快速地实现底部弹窗的多选功能。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Flutter 底部弹窗如何实现多项选择

    多选和单选的不同之处 单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理.但到多选的时候,需要知道当前选中的选项,有选项被点击的时候需要存储下来,当再次被点击的时候要清空这个选项,同时界面还需要同步更新,因此就涉及到状态管理了. 实现方式 在Flutter 中提供了一个 StatefulBuilder 的类,提供了一个 builder方法构建有状态组件,并且提供了状态更新方法,因此在里面完成状态管理. StatefulBuilder(builder: (context1, s

  • flutter实现更新弹窗内容例子(亲测有效)

    什么是Flutter Flutter 是谷歌推出的开发移动UI框架,可以快速的在IOS和Android上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作,并且Flutter是完全免费的,开源的. 总结来说: Flutter是一款移动应用程序SDK,包含框架.widget和工具,为开发人员提供了一种在Android和iOS上构建和部署精美移动应用程序的简单高效的方式. Flutter的优势 快速开发 毫秒级的热重载,修改后,您的应用界面会立即更新.使用丰富的.完全可定制的widg

  • Flutter实现底部弹窗效果

    目录 实现效果 代码结构 基本使用 自定义底部弹窗 总结 在实际开发过程中,经常会用到底部弹窗来进行快捷操作,例如选择一个选项,选择下一步操作等等.在 Flutter 中提供了一个 showModelBottomSheet 方法用于弹出底部弹窗,本篇介绍如何使用底部弹窗. 实现效果 最终实现效果如图片所示,分布演示了基础的,全屏的和自定义的底部弹窗形式. 代码结构 在消息页面 message.dart 中,使用 Column 组件构建了三个按钮,点击每个按钮调用不同的底部弹窗显示.这部分代码不展

  • Flutter多项选择弹窗实现详解

    目录 多选和单选的不同之处 实现方式 界面变更 代码实现 总结 在Flutter 底部弹窗详解一篇中介绍了底部弹窗的实现.发出后有在琢磨如何实现多选,这也是很常用的一个功能.本篇介绍实现多选的思路和实现方式. 多选和单选的不同之处 单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理.但到多选的时候,需要知道当前选中的选项,有选项被点击的时候需要存储下来,当再次被点击的时候要清空这个选项,同时界面还需要同步更新,因此就涉及到状态管理了. 实现方式 在Flutter 中提供了一个

  • Flutter实现底部导航栏创建详解

    目录 添加依赖项 如何使用 功能 属性 主题 预览图 代码 Flutter web问题:Failed to load network image 我的解决办法 参考资料 ConvexBottomBar是一个底部导航栏组件,用于展现凸起的TAB效果,支持多种内置样式与动画交互.你可以在https://appbar.codemagic.app/上找到在线样例. 添加依赖项 在你的项目中去 pubspec.添加依赖项: 添加https://pub.dev/packages/convex_bottom_

  • Android 列表选择框 Spinner详解及实例

    Android 列表选择框 Spinner详解及实例 Spinner 是 Android 的列表选择框,不过 spinner 并不需要显示下拉列表,而是相当于弹出一个菜单供用户选择. Spinner 属性: ● android:spinnerMode:列表显示的模式,有两个选择,为弹出列表(dialog)以及下拉列表(dropdown),如果不特别设置,为下拉列表. ● android:entries:使用<string-array.../>资源配置数据源. ● android:prompt:

  • Go语言数据结构之选择排序示例详解

    目录 选择排序 动画演示 Go 代码实现 总结 选择排序 选择排序(selection sort)是一种原地(in-place)排序算法,适用于数据量较少的情况.由于选择操作是基于键值的且交换操作只在需要时才执行,所以选择排序长用于数值较大和键值较小的文件. 思想: 对一个数组进行排序,从未排序的部分反复找到最小的元素,并将其放在开头. 给定长度为 nnn 的序列和位置索引i=0 的数组,选择排序将: 遍历一遍序列,寻找序列中的最小值.在 [i...n−1] 范围内找出最小值 minValue

  • Flutter EventBus事件总线的应用详解

    目录 前言 EventBus的简介 EventBus的实际应用 总结 前言 flutter项目中,有许多可以实现跨组件通讯的方案,其中包括InheritedWidget,Notification,EventBus等.本文主要探讨的是EventBus事件总线实现跨组件通讯的方法. EventBus的简介 EventBus的核心是基于Streams.它允许侦听器订阅事件并允许发布者触发事件,使得不同组件的数据不需要一层层传递,可以直接通过EventBus实现跨组件通讯. EventBus最主要是通过

  • Flutter之 ListView组件使用示例详解

    目录 ListView的默认构造函数定义 默认构造函数 ListView.builder ListView.separated 固定高度列表 ListView 原理 实例:无限加载列表 添加固定列表头 总结 ListView的默认构造函数定义 ListView是最常用的可滚动组件之一,它可以沿一个方向线性排布所有子组件,并且它也支持列表项懒加载(在需要时才会创建).我们看看ListView的默认构造函数定义: ListView({ ... //可滚动widget公共参数 Axis scrollD

  • Android自定义view实现滚动选择控件详解

    目录 前言 需求 编写代码 主要问题 前言 上篇文章通过一个有header和footer的滚动控件(Viewgroup)学了下MeasureSpec.onMeasure以及onLayout,接下来就用一个滚动选择的控件(View)来学一下onDraw的使用,并且了解下在XML自定义控件参数. 需求 这里就是一个滚动选择文字的控件,还是挺常见的,之前用别人的,现在选择手撕一个,核心思想如下: 1.有三层不同大小及透明度的选项,选中项放在中间 2.接受一个列表的数据,静态时显示三个值,滚动时显示四个

  • Flutter Widget之FutureBuilder使用示例详解

    目录 正文 正文 本质上Flutter和Dart是异步的,Dart是Futures使你能够管理IO而不用担心线程或死锁. 例如,从应用程序外部加载数据需要时间,而Futures允许Dart先处理其他任务直到请求的数据可用. 但是涉及Future时,你如何构建Flutter小部件呢? 输入FutureBuilder,这是处理Futures的构造器 FutureBuilder( future: _data, builder: _myBuilderFunction, ) FutureBuilder让你

  • Flutter Widget 之package mason实现详解

    目录 正文 使用Mason砖块 运行mason make 正文 Flutter有个悠久的传统,便是运行flutter create并删除所有内容,然后在所有标准样板文件(boilerplate)当中尽力复制和粘贴,这很费时又容易出错,而且比报税更无趣,但是是否别无他法? 进入Mason,这是用于欧快速组装新项目或功能的软件包,可以从成为“砖块”的自定义模版中生成代码,而这些模版根据你的项目的特定值呈现 使用Mason砖块 例如想象一下,你正为Flutter新项目使用Mason砖块的pubspec

  • java中switch选择语句代码详解

    switch结构(开关语句)的语法 switch(表达式 ){ --->类型为int.char case 常量1 :--->case 结构可以有多个 //语句块1 break; --->程序跳出switch结构 case 常量n :--->常量的值不能相同 //语句块n break; default:--->和if结构中的 else作用相同 //语句块 break; } 下面看一段代码示例,有详细的注释,大家可以参考: public class SwitchStu{ /* s

随机推荐