Flutter系列教程之(8)——CheckBox多选框及动态更改多选框

目录

1.星级组件使用

2.多选框使用及数据更改

3.完整源码


最近项目需求需要调整页面,记录一下实现过程

这次主要是要实现个评价页面,选择不同的星级显示不同的多选框数据,加上之前也没有使用过CheckBox,今天便是一起讲吧

1.星级组件使用

首先,我们有使用到星级评分组件 在pubspec.yaml文件中添加下面依赖

flutter_simple_rating_bar: ^0.0.3

使用的话页面也是有个例子介绍,我们直接拿来即可使用

RatingBar(//默认选择5星rating: 5,//总星星数目starCount: 5,//星星图标icon: Icon(Icons.star,size: 40,color: Colors.grey,),spacing: 5.0,size: 40,isIndicator: false,//是否可选半星allowHalfRating: true,onRatingCallback:(double value, ValueNotifier<bool> isIndicator) {//value是点击后选中的星星数(即评分),范围为1-rating(我们上面rating为5)},color: Colors.amber,
)

现在我们要根据选择⭐的数目不同,从而显示不同的文字,这过程是动态的,所以我们选择使用StatefulWidget作为页面继承的基类

我们先在State类中加上相应的数据,如下所示

//显示的文字信息
List typeList = ["非常不满意", "不满意", "基本满意", "满意", "非常满意"];//当前选择type的下标
int selectType = 4;

我们文字显示内容是typeList[selectType],我们在星级评分选择的回调函数,更改selecType即可实现更改UI的功能

Column(children: [RatingBar(rating: 5,//默认选择5星starCount: 5,//总星星数目//星星图标icon: Icon(Icons.star,size: 40,color: Colors.grey,),spacing: 5.0,size: 40,isIndicator: false,//是否可选半星allowHalfRating: true,onRatingCallback:(double value, ValueNotifier<bool> isIndicator) {//更改数据同时也要更改UI,所以使用setState方法setState(() {//注意 星级从1开始,selectType是下标,从0开始,需要减1selectType = value.toInt() - 1;});},color: Colors.amber,),//取指定下标的文字内容展示Text(typeList[selectType])],
)

2.多选框使用及数据更改

CheckBox多选框的使用需要定义一个bool类型的数据,每次点击需要更改此数据来改变CheckBox的选择状态

由于我们是使用的列表数据,所以每个数据写个变量不太现实,而且繁琐,所以可以考虑在实体类中加个bool类型的字段,用来存储CheckBox选择的状态

这里,数据我就暂且写死,实际上是要通过调用接口获取的

void initTagData() {var data = """{"code":200,"error":"","ReturnValue":[{"generalstars":"1","tagid":"109759610348409856","tagname":"无理由超过法定办理时间","updatetime":"2020-06-12 17:38:00"},{"generalstars":"1","tagid":"6176177900787350","tagname":"在办事指南之外增加新的审批条件","updatetime":"2020-08-27 00:00:00"},{"generalstars":"1","tagid":"6176177900787351","tagname":"需提供办事指南之外的申报材料","updatetime":"2020-08-27 00:00:00"},{"generalstars":"1","tagid":"7176177890787535","tagname":"无理由超过法定办理时间","updatetime":"2020-08-27 00:00:00"},{"generalstars":"2","tagid":"6176177900787349","tagname":"未在承诺时间内办结","updatetime":"2020-08-27 00:00:00"},{"generalstars":"2","tagid":"6176177900787347","tagname":"没有提供材料样本","updatetime":"2020-08-27 00:00:00"},{"generalstars":"2","tagid":"6176177900787348","tagname":"没有提供材料清单","updatetime":"2020-08-27 00:00:00"},{"generalstars":"3","tagid":"119596473292723200","tagname":"22222","updatetime":"2020-06-12 17:38:00"},{"generalstars":"3","tagid":"6176177900787346","tagname":"在承诺的时间内办结","updatetime":"2020-08-27 00:00:00"},{"generalstars":"3","tagid":"6176177900787345","tagname":"提供申报材料样本","updatetime":"2020-08-27 00:00:00"},{"generalstars":"3","tagid":"6176177900787344","tagname":"一次性告知需要补正的材料","updatetime":"2020-08-27 00:00:00"},{"generalstars":"4","tagid":"6176177900787340","tagname":"填写一张表单就可以完成申报","updatetime":"2020-08-27 00:00:00"},{"generalstars":"4","tagid":"6176177900787341","tagname":"在线提交材料窗口核验","updatetime":"2020-08-27 00:00:00"},{"generalstars":"4","tagid":"6176177900787342","tagname":"一张清单告知全部申报材料","updatetime":"2020-08-27 00:00:00"},{"generalstars":"5","tagid":"7176177890787335","tagname":"一窗受理一次办结","updatetime":"2020-08-27 00:00:00"},{"generalstars":"5","tagid":"7176177890787235","tagname":"可以先受理后补材料","updatetime":"2020-08-27 00:00:00"},{"generalstars":"5","tagid":"7176177890787435","tagname":"不用提交证明","updatetime":"2020-08-27 00:00:00"}]}""";Map<String, dynamic> responseData = jsonDecode(data);var tagListModel = TagListModel.fromJson(responseData);if (tagListModel.code == 200) {//注意要使用setState,才会使UI发生变化(因为网络请求是耗时任务,可能界面渲染完毕后才能请求到数据)setState(() {tagList.addAll(tagListModel.tagItems);});}}

TagListModel是生成的实体类,生成的步骤已经在上篇文章讲解到,这里就不在赘述了

按照上面说的思路,我们在TagListModel的实体类中**(其实是在TagItem中)**,添加一个bool类型的字段,用来作为存储CheckBox选择的状态,

这里使用插件生成的实体类(TagListModel里面还包含有个实体类),原本应该是ReturnValue,但为了方便,我将其改了个名字TagItem

Flutter中的CheckBox是只有一个框,并不包含文字,所以我们得组合一个文本,拼成一个Widget,_tagView()这个方法就是每个选项

Widget _tagView(item) {var str = item.tagname;return InkWell(child: Row(children: <Widget>[Checkbox(value: item.flag,activeColor: Colors.blue,onChanged: (bool val) {// val 是布尔值this.setState(() {item.flag = val;});},),Text(str),],),onTap: () {setState(() {item.flag = !item.flag;});},);

这里最外层使用了InkWell,是因为其有onTag的点击事件方法 点击整行都可以去改变CheckBox的状态,用户体验比较友好,如果没有的话,只能点击CheckBox的框来改变状态

有了上面的一个子项,现在我们需要构建一个多选选项列表(列表包含N个_tagView组件)

先声明两个数组,用来存放数据

//标签数据(存放所有数据)
List<TagItem> tagList = [];//临时存放的数据,后面评价提交需要
List<TagItem> tempTagList = [];

这里为什么需要两个数组呢?

主要是考虑到后面需要获取勾选的数据,所以才考虑再多加一个临时的列表

每次改变星级的时候,列表选项的数据就会改变,之后我们只需要去这个临时列表中筛选状态为true的数据即可

List<Widget> _tagList() {List<Widget> widgetList = [];var list = this.tagList;tempTagList.clear();var star = selectType.toInt() + 1;//匹配相同星级数据for (var i = 0; i < list.length; i++) {var item = list[i];if (item.generalstars == star.toString()) {//存在临时表中,之后可以快速查找用户的选择tempTagList.add(item);var row = _tagView(item);widgetList.add(row);}}return widgetList;
}

由于数据较少,可以使用Column用来包裹上面的组件_tagList

//标签选项
Container(decoration: BoxDecoration(color: Colors.white),padding: EdgeInsets.fromLTRB(10, 0, 15, 5),child: Column(children: _tagList(),)
)

由于提交标签需要传标签的id,而且需要逗号隔开,所以需要遍历临时选项列表,处理一下即可

3.完整源码

//处理标签
var tagId = "";
for (var i = 0; i < tempTagList.length; i++) {var item = tempTagList[i];//查找选择的标签数据if (item.flag) {tagId += item.tagid + ",";}
}
if (tagId.length>0) {tagId = tagId.substring(0, tagId.length - 1);
}
print(tagId);
import 'dart:convert';import 'package:flutter/material.dart';
import 'package:flutter_demo/model/tag_list_model.dart';
import 'package:flutter_simple_rating_bar/flutter_simple_rating_bar.dart';class CheckBoxPage extends StatefulWidget {@overrideState<StatefulWidget> createState() {return new CheckBoxState();}
}class CheckBoxState extends State<CheckBoxPage> {//标签数据List<TagItem> tagList = [];//临时标签,后面评价提交需要List<TagItem> tempTagList = [];List typeList = ["非常不满意", "不满意", "基本满意", "满意", "非常满意"];//当前选择type的下标int selectType = 4;@overridevoid initState() {//初始化数据(这里是暂时写死,实际中这里是调用接口)initTagData();}void initTagData() {var data = """{"code":200,"error":"","ReturnValue":[{"generalstars":"1","tagid":"109759610348409856","tagname":"无理由超过法定办理时间","updatetime":"2020-06-12 17:38:00"},{"generalstars":"1","tagid":"6176177900787350","tagname":"在办事指南之外增加新的审批条件","updatetime":"2020-08-27 00:00:00"},{"generalstars":"1","tagid":"6176177900787351","tagname":"需提供办事指南之外的申报材料","updatetime":"2020-08-27 00:00:00"},{"generalstars":"1","tagid":"7176177890787535","tagname":"无理由超过法定办理时间","updatetime":"2020-08-27 00:00:00"},{"generalstars":"2","tagid":"6176177900787349","tagname":"未在承诺时间内办结","updatetime":"2020-08-27 00:00:00"},{"generalstars":"2","tagid":"6176177900787347","tagname":"没有提供材料样本","updatetime":"2020-08-27 00:00:00"},{"generalstars":"2","tagid":"6176177900787348","tagname":"没有提供材料清单","updatetime":"2020-08-27 00:00:00"},{"generalstars":"3","tagid":"119596473292723200","tagname":"22222","updatetime":"2020-06-12 17:38:00"},{"generalstars":"3","tagid":"6176177900787346","tagname":"在承诺的时间内办结","updatetime":"2020-08-27 00:00:00"},{"generalstars":"3","tagid":"6176177900787345","tagname":"提供申报材料样本","updatetime":"2020-08-27 00:00:00"},{"generalstars":"3","tagid":"6176177900787344","tagname":"一次性告知需要补正的材料","updatetime":"2020-08-27 00:00:00"},{"generalstars":"4","tagid":"6176177900787340","tagname":"填写一张表单就可以完成申报","updatetime":"2020-08-27 00:00:00"},{"generalstars":"4","tagid":"6176177900787341","tagname":"在线提交材料窗口核验","updatetime":"2020-08-27 00:00:00"},{"generalstars":"4","tagid":"6176177900787342","tagname":"一张清单告知全部申报材料","updatetime":"2020-08-27 00:00:00"},{"generalstars":"5","tagid":"7176177890787335","tagname":"一窗受理一次办结","updatetime":"2020-08-27 00:00:00"},{"generalstars":"5","tagid":"7176177890787235","tagname":"可以先受理后补材料","updatetime":"2020-08-27 00:00:00"},{"generalstars":"5","tagid":"7176177890787435","tagname":"不用提交证明","updatetime":"2020-08-27 00:00:00"}]}""";Map<String, dynamic> responseData = jsonDecode(data);var tagListModel = TagListModel.fromJson(responseData);if (tagListModel.code == 200) {//注意要使用setState,才会使UI发生变化(因为网络请求是耗时任务,可能界面渲染完毕后才能请求到数据)setState(() {tagList.addAll(tagListModel.tagItems);});}}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("评价"),),body: Column(children: [Container(decoration: BoxDecoration(color: Colors.white),padding: EdgeInsets.fromLTRB(15, 0, 15, 10),child: Wrap(spacing: 10,children: [Center(child: Column(children: [RatingBar(rating: 5,//默认选择5星starCount: 5,//总星星数目//星星图标icon: Icon(Icons.star,size: 40,color: Colors.grey,),spacing: 5.0,size: 40,isIndicator: false,//是否可选半星allowHalfRating: true,onRatingCallback:(double value, ValueNotifier<bool> isIndicator) {//更改数据同时也要更改UI,所以使用setState方法setState(() {//注意 星级从1开始,selectType是下标,从0开始,需要减1selectType = value.toInt() - 1;});},color: Colors.amber,),_tipText()],),)],),),//标签选项Container(decoration: BoxDecoration(color: Colors.white),padding: EdgeInsets.fromLTRB(10, 0, 15, 5),child: Column(children: _tagList(),)),Container(decoration: BoxDecoration(color: Colors.white),padding: EdgeInsets.fromLTRB(10, 0, 15, 5),child: FlatButton(child: Text("提交"),onPressed: () {//处理标签var tagId = "";for (var i = 0; i < tempTagList.length; i++) {var item = tempTagList[i];//查找选择的标签数据if (item.flag) {tagId += item.tagid + ",";}}if (tagId.length>0) {tagId = tagId.substring(0, tagId.length - 1);}print(tagId);},)),],),);}Widget _tipText() {//根据selectType变更UIreturn Text(typeList[selectType]);}List<Widget> _tagList() {List<Widget> widgetList = [];var list = this.tagList;tempTagList.clear();var star = selectType.toInt() + 1;for (var i = 0; i < list.length; i++) {var item = list[i];if (item.generalstars == star.toString()) {//存在临时表中,之后可以快速查找用户的选择tempTagList.add(item);var row = _tagView(item);widgetList.add(row);}}return widgetList;}Widget _tagView(item) {var str = item.tagname;return InkWell(child: Row(children: <Widget>[Checkbox(value: item.flag,activeColor: Colors.blue,onChanged: (bool val) {// val 是布尔值this.setState(() {item.flag = val;});},),Text(str),],),onTap: () {setState(() {item.flag = !item.flag;});},);}
}

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

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

相关文章

神经网络|(十一)|神经元和神经网络

【1】引言 前序已经了解了基本的神经元知识&#xff0c;相关文章链接为&#xff1a; 神经网络|(一)加权平均法&#xff0c;感知机和神经元-CSDN博客 神经网络|(二)sigmoid神经元函数_sigmoid函数绘制-CSDN博客 神经网络|(三)线性回归基础知识-CSDN博客 把不同的神经元通过…

微软Office 2016-2024 x86直装版 v16.0.18324 32位

微软 Office 是一款由微软公司开发的办公软件套装&#xff0c;能满足各种办公需求。包含 Word、Excel、PowerPoint、Outlook 和 OneNote 等软件。Word 有强大文档编辑功能和多人协作&#xff1b;Excel 可处理分析大量数据及支持宏编程&#xff1b;PowerPoint 用于制作演示文稿且…

Python从0到100(八十九):Resnet、LSTM、Shufflenet、CNN四种网络分析及对比

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

TinyEngine v2.2版本发布:支持页面嵌套路由,提升多层级路由管理能力开发分支调整

2025年春节假期已过&#xff0c;大家都带着慢慢的活力回到了工作岗位。为了让大家在新的一年继续感受到 Tiny Engine 的成长与变化&#xff0c;我们很高兴地宣布&#xff1a;TinyEngine v2.2版本正式发布&#xff01;本次更新带来了重要的功能增强------页面支持嵌套路由&#…

线程(Thread)

一、概念 线程&#xff1a;线程是一个轻量级的进程 二、线程的创建 1、线程的空间 &#xff08;1&#xff09;进程的空间包括&#xff1a;系统数据段、数据段、文本段 &#xff08;2&#xff09; 线程位于进程空间内部 &#xff08;3&#xff09; 栈区独享、与进程共享文本段、…

【含文档+PPT+源码】基于微信小程序的校园志愿者管理系统的设计与实现

项目介绍 本课程演示的是一款 基于微信小程序的校园志愿者管理系统的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…

yolov8,yolo11,yolo12 服务器训练到部署全流程 笔记

正在进行中&#xff0c;随时更新 一. Anaconda配置 1.安装anaconda (1)下载.sh文件 Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror (2)scp到服务器后&#xff0c;运行安装包 bash Anaconda3-2020.07-Linux-x86_64.sh (3)安装anacond…

CentOS vs Ubuntu - 常用命令深度对比及最佳实践指南20250302

CentOS vs Ubuntu - 常用命令深度对比及最佳实践指南 引言 在 Linux 服务器操作系统领域&#xff0c;CentOS 和 Ubuntu 是广泛采用的发行版。它们在命令集、默认工具链及生态系统方面各有特点。本文深入剖析 CentOS 与 Ubuntu 在常用命令层面的异同&#xff0c;并结合实践案例…

Java并发编程之可见性、原子性和有序性

引言 CPU缓存与内存产生的一致性问题(可见性) CPU时间片切换产生的原子性问题 CPU指令编译优化产生的有序性问题 并发编程问题的根源 CPU、内存、I/O设备三者速度差异一直是 核心矛盾 三者速度差异可形象描述为:天上一天(CPU),地上一年(内存),地下十年(I/O) 根据木桶理…

【Maui】系统找不到指定的文件Xamarin.Android.Aapt2.targets

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI&#xff0c;可从单个共享代码库开发可在 And…

【STM32+cubemx】0024 HAL库开发:IAP(在应用编程)的实现

IAP在应用编程&#xff08;In-Application Programming&#xff09;&#xff0c;指的是MCU在运行应用程序时&#xff0c;能接收新的烧写文件&#xff0c;并更新到自身的程序存储器中。即可以在应用程序运行时在线升级。 本节我们通过一个简单的例子&#xff0c;来实现STM32的IA…

【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 欢迎点赞、收藏、关注&#xff0c;跟上我的更新节奏 &#x1f4da;欢迎订阅专栏…

【Linux第一弹】Linux基础指令(上)

目录 1.ls指令 1.1 ls使用实例 2.pwd指令 3.cd指令 3.1 cd使用实例 4.touch指令 4.1touch使用实例 5.mkdir指令 5.1mkdir使用实例 6.rmdir指令和rm指令 6.1 rmdir指令使用实例->: 6.2 rm指令使用实例 7.man指令 8.cp指令 8.1 cp 使用实例 9.mv指令 9.1mv使用…

智能合约安全 | 合约无效化攻击

目录&#xff1a; 智能合约安全 合约无效化攻击 合约自毁函数 selfdestruct 攻击实现 漏洞防御 总结 智能合约安全 合约无效化攻击 合约无效化攻击类同于web安全中的逻辑漏洞中的一种 我们这里拿一个典型的例子来讲解 有这样一份智能合约, 每个人可以向其中发送1 eth 第七个…

蓝桥 发现环

0发现环 - 蓝桥云课 找到环 不过在最近一次维护网络时&#xff0c;管理员误操作使得某两台电脑之间增加了一条数据链接&#xff0c;于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径&#xff0c;使得这些电脑上的数据传输出现了BUG。 为了恢复正常传输&am…

weaviate 安装与测试

weaviate 安装 前提条件&#xff1a;docker安装完成 步骤&#xff1a; 开启docker 在终端运行命令 docker run -p 8080:8080 -p 50051:50051 cr.weaviate.io/semitechnologies/weaviate:1.29.0 weaviate 测试 python-client安装代码测试 import weaviate client weaviat…

SpringBoot原理-02.自动配置-概述

一.自动配置 所谓自动配置&#xff0c;就是Spring容器启动后&#xff0c;一些配置类、bean对象就自动存入了IOC容器当中&#xff0c;而不需要我们手动声明&#xff0c;直接从IOC容器中引入即可。省去了繁琐的配置操作。 我们可以首先将spring项目启动起来&#xff0c;里面有一…

内容中台与企业内容管理架构解析

内容中台技术架构解析 内容中台的技术架构以数据资产化和服务API化为核心&#xff0c;通过解耦内容生产与消费环节构建数字化基础设施。其架构通常包含统一内容池、智能处理引擎和开放接口层三大模块&#xff1a;统一内容池通过标准化元数据模型对多源异构内容进行结构化存储&…

DeepSeek开源周Day2:DeepEP - 专为 MoE 模型设计的超高效 GPU 通信库

项目地址&#xff1a;https://github.com/deepseek-ai/DeepEP 开源日历&#xff1a;2025-02-24起 每日9AM(北京时间)更新&#xff0c;持续五天 (2/5)&#xff01; ​ ​ 引言 在大模型训练中&#xff0c;混合专家模型&#xff08;Mixture-of-Experts, MoE&#xff09;因其动…

密码学(哈希函数)

4.1 Hash函数与数据完整性 数据完整性&#xff1a; 检测传输消息&#xff08;加密或未加密&#xff09;的修改。 密码学Hash函数&#xff1a; 构建某些数据的简短“指纹”&#xff1b;如果数据被篡改&#xff0c;则该指纹&#xff08;以高概率&#xff09;不再有效。Hash函数…