当前位置: 首页 > news >正文

二级列表联动

介绍

本示例主要介绍了List组件实现二级联动(Cascading List)的场景。 该场景多用于商品种类的选择、照片不同类型选择等场景。

效果图

使用说明

  1. 滑动二级列表侧控件(点击没用),一级列表随之滚动。(当最后一次触屏在一级列表,则滑动二级列表,一级列表固定不动)
  2. 点击一级列表(滑动没用),二级列表随之滚动。
  3. 点击一级列表可视区域边界时,选中类别向中间移动

实现思路

  1. 使用两个List。
  2. 一二级列表分别绑定不同的Scroller对象,一级列表(tagLists)绑定classifyScroller对象,二级列表绑定scroller对象。
  3. 维护records数组,一个item数量的前缀和,records[i]表示第i+1种类别的第一个item之前有多少个item,这个数值等于records[i]表示第i+1种类别的第一个item在itemList的下标
  4. 使用List的onTouch,.onScrollIndex组件方法,判断最后一次触屏是否在一级列表,和一级列表的可视区域
  5. 实现itemFindClassIndex(itemIndex:number),itemFindClassIndex(itemIndex:number);
  6. 点击一级列表后,通过一级列表的索引获取二级列表的索引,调用scrollToIndex方法将一二级列表滚动到指定索引值
  7. 滑动二级列表触发组件滚动事件后,获取到列表可视区域第一个item对应的索引值,通过二级列表索引获取一级列表索引,调用scrollToIndex方法将一级列表滚动到指定索引值
  8. 监听curClass变量,onClassChange点击一级列表可视区域边界时,一级列表将选中类别向中间移动

样例代码

interface IRange {start: number;end: number;
}//可视区间的开始和结尾
@Entry
@Component
struct Index {@State itemList:string[]=[];				// 二级列表数据@State classList:string[]=[];				// 一级列表数据@State @Watch('onClassChange') curClass:number=-1//当前类别下标readonly eachClassCount:number[]=[6,4,4,6,5,6,4,4,6,5];//每一个类别item的数量private classScroller:Scroller=new Scroller();private itemScroller:Scroller=new Scroller();private records:number[]=[];  			//一个前缀和 二级列表分组count数量private classVisualRange:IRange={start:0,end:0};private isClickClassList:boolean=false; 	//上一次点击是否点击的是类别 true:滑动二级列表,一级列表不跟着一起变化 flase:滑动二级列表,一级列表跟着一起变化aboutToAppear(): void {/*造数据*/for(let i=0;i<10;i++){this.classList[this.classList.length]=`${i+1}`for(let j=0;j<this.eachClassCount[i];j++){this.itemList[this.itemList.length]=`${i+1}类 第${j+1}`}}this.records[0]=0;for(let i=1;i<=10;i++){//最后多一个,方便二级item寻找一级classthis.records[i]=this.records[i-1]+this.eachClassCount[i-1];}}itemFindClassIndex(itemIndex:number):number{let classIndex:number=0;for(let i=0;i<10;i++){if(this.records[i]<=itemIndex&&itemIndex<this.records[i+1]){classIndex=i;break;}}return classIndex;}classFindItemIndex(classIndex:number):number{return this.records[classIndex];}onClassChange(){const start=this.classVisualRange.start,end=this.classVisualRange.end;if(this.curClass===start||this.curClass===start+1){this.classScroller.scrollToIndex(Math.max(0,this.curClass-1),true)//向上一格作为可视区域第一个}else if(this.curClass===end||this.curClass===end-1){this.classScroller.scrollToIndex(Math.min(10,this.curClass+1),true)//向下一格作为可视区域第一个}}build() {Row() {/*** 一级列表*/List({scroller:this.classScroller,space:10, initialIndex: 0}){ForEach(this.classList,(classItem:string,index:number)=>{ListItem(){Text(classItem).width('100%').height('15%').backgroundColor(this.curClass===index?Color.Green:Color.Pink).onClick(()=>{let itemIndex=this.classFindItemIndex(index);this.curClass=index;this.itemScroller.scrollToIndex(itemIndex,true)})}})}.width('30%').height('100%').margin({left:20,right:20}).scrollBar(BarState.Off).onTouch(()=>{this.isClickClassList=true;}).onScrollIndex((start,end)=>{this.classVisualRange.start=start;this.classVisualRange.end=end;})/*** 二级列表*/List({scroller:this.itemScroller,space:10}){ForEach(this.itemList,(item:string,index:number)=>{ListItem(){Text(item).width('100%').height('17%').backgroundColor('#999999').onClick(()=>{let classIndex=this.itemFindClassIndex(index);this.curClass=classIndex;this.classScroller.scrollToIndex(classIndex,true)})}})}.width('70%').height('100%').margin({left:20,right:20}).scrollBar(BarState.Off).onTouch(()=>{this.isClickClassList=false;})// 性能知识点:onScrollIndex事件在列表滚动时频繁执行,在回调中需要尽量减少耗时和冗余操作,例如减少不必要的日志打印.onScrollIndex((start,end)=>{//二级列表滑动,判断一级列表是否一起滑动if(!this.isClickClassList){let classIndex=this.itemFindClassIndex(start);this.curClass=classIndex;this.classScroller.scrollToIndex(classIndex,true)/*** scrollToIndex(value: number, smooth?: boolean, align?: ScrollAlign)* 性能知识点:开启smooth动效时,会对经过的所有item进行加载和布局计算,当大量加载item时会导致性能问题。*/}})}.height('100%').width('100%')}
}

扩展

  1. 把ForEach换成LazyEach,懒加载
  2. 当种类较多时,要实现“点击一级列表可视区域边界时,选中类别向中间移动”,改进本案例会出现的问题

相关文章:

二级列表联动

介绍 本示例主要介绍了List组件实现二级联动&#xff08;Cascading List&#xff09;的场景。 该场景多用于商品种类的选择、照片不同类型选择等场景。 效果图 使用说明&#xff1a; 滑动二级列表侧控件&#xff08;点击没用&#xff09;&#xff0c;一级列表随之滚动。&…...

「C/C++」C++ 标准库 之 #include<sstream> 字符串流库

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...

深入理解跨域资源共享(CORS)安全问题原理及解决思路

目录 引言 CORS 基础 CORS 安全问题原理 解决思路 结论 引言 跨域资源共享&#xff08;CORS, Cross-Origin Resource Sharing&#xff09;是现代Web应用中不可或缺的一部分&#xff0c;特别是在前后端分离的架构中。CORS允许一个域上的Web应用请求另一个域上的资源&#…...

【汽车租聘管理与推荐】Python+Django网页界面+推荐算法+管理系统网站

一、介绍 汽车租聘管理与推荐系统。本系统使用Python作为主要编程语言&#xff0c;前端采用HTML、CSS、BootStrap等技术搭建前端界面&#xff0c;后端采用Django框架处理用户的请求。创新点&#xff1a;使用协同过滤推荐算法实现对当前用户个性化推荐。 其主要功能如下&#…...

Linux常见指令大全(必要+知识点)

目录 ls 指令☑️ 在Windows中会自动显示当前目录当中的所有子目录与文件&#xff0c;但是在Linux中要用到ls指令。 语法&#xff1a; ls [选项][目录或文件] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以…...

iOS用rime且导入自制输入方案

iPhone 16 的 cantonese 只能打传统汉字&#xff0c;没有繁简转换&#xff0c;m d sh d。考虑用「仓」输入法 [1] 使用 Rime 打字&#xff0c;且希望导入自制方案 [2]。 仓输入法有几种导入方案的方法&#xff0c;见 [3]&#xff0c;此处记录 wifi 上传法。准备工作&#xff1…...

Linux 进程终止 进程等待

目录 进程终止 退出码 错误码 代码异常终止(信号详解) exit _exit 进程等待 概念 等待的原因 wait 函数原型 参数 返回值 监控脚本 waitpid 概念 函数原型 参数 返回值 WIFEXITED(status) WEXITSTATUS(status) 问题 为什么不用全局变量获得子进程的退出信…...

VBA 64位API声明语句第003讲

跟我学VBA&#xff0c;我这里专注VBA, 授人以渔。我98年开始&#xff0c;从源码接触VBA已经20余年了&#xff0c;随着年龄的增长&#xff0c;越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友&#xff0c;都来学习VBA,利用VBA,起码可以提高…...

【问题记录】解决VMware虚拟机中鼠标侧键无法使用的问题

前言 有项目需要在Linux系统中开发&#xff0c;因为要测试Linux中相关功能&#xff0c;要用到shell&#xff0c;在Windows中开发太麻烦了&#xff0c;因此我选择使用UbuntuXfce4桌面来开发&#xff0c;这里我用到了Linux版本的IDEA&#xff0c;除了快捷键经常和系统快捷键冲突…...

Naive UI 级联选择器 Cascader的:render-lable怎么使用(Vue3 + TS)(鼠标悬停该条数据的时候展示全部内容)

项目场景&#xff1a; 在渲染Cascader级联选择器后&#xff0c;当文字过长的时候&#xff0c;多出来的部分会显示成省略号&#xff0c;这使我们不能很清晰的看到该条数据的完整信息&#xff0c;就需要加一个鼠标悬停展示完整内容。 解决方案&#xff1a; vue&#xff1a; &l…...

vue元素里面的 js对象中,:style后面里属性名不支持这种带-的写法(background-color)

首先要知道&#xff0c;在这个:style里面&#xff0c;虽然可以用 {属性: 属性值 , 属性: 属性值} 这种方方式来写很多属性&#xff0c;但也仅限于width这种普通属性&#xff0c;像background-color这种带-的特殊标签是不支持直接写的&#xff1b; <div class"box&quo…...

Git 常用命令与开发流程总结

引言 在我之前面试过程中&#xff0c;经常会问到关于公司使用什么代码版本管理工具。 无非是考察咱们是否用过 Git和SVN。 现在公司选择的工具直接影响到项目的开发流程和协作效率。当前市面上&#xff0c;Git 和 SVN&#xff08;Subversion&#xff09;是两种流行的版本控制系…...

链表中插入新的节点

/* 节点结构体定义 */ struct xLIST_ITEM {TickType_t xItemValue; /* 辅助值&#xff0c;用于帮助节点做顺序排列 */ struct xLIST_ITEM * pxNext; /* 指向链表下一个节点 */ struct xLIST_ITEM * pxPrevious; /* 指向链表前一个节点 */ void * pvOw…...

AUTOSAR从入门到精通-BswM模块(二)

目录 前言 算法原理 BswM接口端口 BswM功能描述 模式仲裁 仲裁规则(Arbitration Rules) 模式仲裁来源 模式仲裁过程 模式条件(ModeCondition) 逻辑表达式(LogicExpressions) 模式控制 模式处理 操作执行 模式控制过程 模式控制基本流程 BswM Interfaces and …...

Spring DispatcherServlet详解

文章目录 Spring DispatcherServlet详解一、引言二、DispatcherServlet的初始化与工作流程1、DispatcherServlet的初始化1.1、加载配置和建立WebApplicationContext1.2、初始化策略 2、DispatcherServlet的工作流程2.1、请求分发2.2、代码示例 三、总结 Spring DispatcherServl…...

JS | 软件制作的流程是什么?

目录 一、 需求分析 二、 系统设计 三、 编码实现 四、 测试验证 五、 部署上线 六、 维护更新 软件制作的流程主要包含需求分析、系统设计、编码实现、测试验证、部署上线和维护更新。其中&#xff0c;需求分析是基础&#xff0c;它决定了软件的功能和性能&#xff1b;通…...

简单工厂模式

引言 简单工厂模式并不属于23种设计模式&#xff0c;它是工厂方法模式的“小弟”&#xff0c;由于日常编程中大家会经常用到&#xff0c;只不过没有察觉&#xff0c;因此下文将详解简单工厂模式。 1.概念 简单工厂模式(Simple Factory Pattern)&#xff1a;又称为静态工厂方法(…...

【django】Django REST Framework 序列化与反序列化详解

目录 1、什么是序列化和反序列化&#xff1f; 2、Django REST Framework中的序列化和反序列化 3、安装与配置&#xff08;第10章是从零开始&#xff09; 3.1 安装 3.2 配置 4、基本使用 4.1 创建序列化器 4.2 使用序列化器&#xff08;将数据序列化返回给前端&#xff…...

【Golang】Golang的Map的线程安全问题

文章目录 前言一、场景介绍二、线程安全的Map的使用四、总结 前言 在 Golang 编程中&#xff0c;map 是一种常用的数据结构&#xff0c;用于存储键值对。然而&#xff0c;Golang 的 map 在并发访问时是线程不安全的。如果多个 goroutine 同时读写同一个 map&#xff0c;可能会…...

指向指针的指针+ 值传递的理解

//17、下面的程序会出现什么结果 #include #include void getmemory(char *p) { p(char *) malloc(100); strcpy(p,”hello world”); } int main( ) { char *strNULL; getmemory(str); printf(“%s/n”,str); free(str); return 0; } // 程序崩溃&#xff0c…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...