【鸿蒙 HarmonyOS NEXT】组件嵌套滚动:nestedScroll

ops/2024/10/22 14:27:55/

✨本人自己开发的开源项目:土拨鼠充电系统

✨踩坑不易,还希望各位大佬支持一下,在GitHub给我点个 Start ⭐⭐👍👍

GitHub开源项目地址👉:https://github.com/cheinlu/groundhog-charging-system

一、背景

当滚动组件进行嵌套关系时,如果两个组件需要同时滚动可能会产生互斥效果,使用nestedScroll属性来解决嵌套组件的滚动问题

可滚动组件:Scroll、List、WaterFlow,这些组件中都有包含nestedScroll属性,用于解决组件嵌套的滚动联动

二、场景

tabs嵌套list组件,当tabs切换页签时,会与list组件的滚动出现互斥效果,期望按住文本或按钮区域都能实现切换页签效果

具体描述:

tabs下面展示文本信息与按钮,其中按钮是用list组件完成的,当按钮多的情况下是可以滚动按钮,目前问题是按住文本区域是可以左右切换tabs页签的,按住按钮区域切换tab就不行,怀疑是list滚动与tab页签切换互斥了

三、具体实现

3.1、示例代码

@Entry
@Component
struct TabsExample {@State fontColor: string = '#182431'@State selectedFontColor: string = '#007DFF'@State currentIndex: number = 0private controller: TabsController = new TabsController()@BuildertabBuilder(index: number, name: string) {Column() {Text(name).fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor).fontSize(16).fontWeight(this.currentIndex === index ? 500 : 400).lineHeight(22).margin({ top: 17, bottom: 7 })Divider().strokeWidth(2).color('#007DFF').opacity(this.currentIndex === index ? 1 : 0)}.width('100%')}build() {Column() {Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {TabContent() {OrderList({ type: '1' })}.tabBar(this.tabBuilder(0, 'green')).gesture(PanGesture(new PanGestureOptions({ direction: PanDirection.Right })))TabContent() {OrderList({ type: '2' })}.tabBar(this.tabBuilder(1, 'blue'))TabContent() {OrderList({ type: '3' })}.tabBar(this.tabBuilder(2, 'yellow'))TabContent() {OrderList({ type: '4' })}.tabBar(this.tabBuilder(3, 'pink')).gesture(PanGesture(new PanGestureOptions({ direction: PanDirection.Left })))}.vertical(false).barMode(BarMode.Fixed).barWidth(360).barHeight(56).animationDuration(400).onChange((index: number) => {this.currentIndex = index}).width(360).height(296).margin({ top: 52 }).backgroundColor('#F1F3F5')}.width('100%')}
}@Component
struct OrderList {@Prop type: stringbuild() {Column() {Column({ space: 30 }) {Row() {Text('文本' + this.type)}Row() {Text('文本' + this.type)}Row() {Text('文本' + this.type)}}.width('100%').height(150)List() {ListItem() {Row() {Text('取消订单' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}ListItem() {Row() {Text('查看发票' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}ListItem() {Row() {Text('申请发票' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}ListItem() {Row() {Text('退换货' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}ListItem() {Row() {Text('去支付' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}}.listDirection(Axis.Horizontal).scrollBar(BarState.Off).edgeEffect(EdgeEffect.None).width('100%')}.width('100%')}
}

3.2、实现效果 

3.3、完成预期效果:按住按钮区域也能切换页签

解决方法:给list添加nestedScroll属性,解决嵌套组件的滚动问题

详细代码:


@Entry
@Component
struct TabsExample {@State fontColor: string = '#182431'@State selectedFontColor: string = '#007DFF'@State currentIndex: number = 0private controller: TabsController = new TabsController()@BuildertabBuilder(index: number, name: string) {Column() {Text(name).fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor).fontSize(16).fontWeight(this.currentIndex === index ? 500 : 400).lineHeight(22).margin({ top: 17, bottom: 7 })Divider().strokeWidth(2).color('#007DFF').opacity(this.currentIndex === index ? 1 : 0)}.width('100%')}build() {Column() {Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {TabContent() {OrderList({ type: '1' })}.tabBar(this.tabBuilder(0, 'green')).gesture(PanGesture(new PanGestureOptions({ direction: PanDirection.Right })))TabContent() {OrderList({ type: '2' })}.tabBar(this.tabBuilder(1, 'blue'))TabContent() {OrderList({ type: '3' })}.tabBar(this.tabBuilder(2, 'yellow'))TabContent() {OrderList({ type: '4' })}.tabBar(this.tabBuilder(3, 'pink')).gesture(PanGesture(new PanGestureOptions({ direction: PanDirection.Left })))}.vertical(false).barMode(BarMode.Fixed).barWidth(360).barHeight(56).animationDuration(400).onChange((index: number) => {this.currentIndex = index}).width(360).height(296).margin({ top: 52 }).backgroundColor('#F1F3F5')}.width('100%')}
}@Component
struct OrderList {@Prop type: stringbuild() {Column() {Column({ space: 30 }) {Row() {Text('文本' + this.type)}Row() {Text('文本' + this.type)}Row() {Text('文本' + this.type)}}.width('100%').height(150)List() {ListItem() {Row() {Text('取消订单' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}ListItem() {Row() {Text('查看发票' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}ListItem() {Row() {Text('申请发票' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}ListItem() {Row() {Text('退换货' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}ListItem() {Row() {Text('去支付' + this.type).fontSize(13).fontColor('#222427')}.padding({left: 12,right: 12,top: 5,bottom: 5}).border({width: 1,radius: 4,color: '#C9CED3',style: BorderStyle.Solid})}}.listDirection(Axis.Horizontal).scrollBar(BarState.Off).edgeEffect(EdgeEffect.None).width('100%').nestedScroll({scrollForward: NestedScrollMode.SELF_FIRST,scrollBackward: NestedScrollMode.SELF_FIRST})}.width('100%')}
}

四、nestedScroll介绍

nestedScroll:设置向前向后两个方向上的嵌套滚动模式,实现与父组件的滚动联动。

参数名类型必填说明
valueNestedScrollOptions嵌套滚动选项。

NestedScrollOptions对象说明

名称类型必填描述
scrollForwardNestedScrollMode滚动组件往末尾端滚动时的嵌套滚动选项。
scrollBackwardNestedScrollMode滚动组件往起始端滚动时的嵌套滚动选项。

NestedScrollMode枚举说明

名称描述
SELF_ONLY只自身滚动,不与父组件联动。
SELF_FIRST自身先滚动,自身滚动到边缘以后父组件滚动。父组件滚动到边缘以后,如果父组件有边缘效果,则父组件触发边缘效果,否则子组件触发边缘效果。
PARENT_FIRST父组件先滚动,父组件滚动到边缘以后自身滚动。自身滚动到边缘后,如果有边缘效果,会触发自身的边缘效果,否则触发父组件的边缘效果。
PARALLEL自身和父组件同时滚动,自身和父组件都到达边缘以后,如果自身有边缘效果,则自身触发边缘效果,否则父组件触发边缘效果。

http://www.ppmy.cn/ops/112835.html

相关文章

git一个项目关联多个远程仓库

一行代码就行: git remote set-url origin [想要关联的远程仓库地址]想要关联哪个就切换哪个 或者不用每次切换,集中管理: Git->Manage Remotes 点击“”,填入Name和想要关联的远程库地址 每次push时执行命令 git push [为…

Mysql 视图存储过程触发器

初识: 在 MySQL 中,视图(View)、存储过程(Stored Procedure)和触发器(Trigger)是用于管理和操作数据库的高级功能。它们各自有不同的用途和优势。 2. 视图 (View) 视图是一个虚拟表,它是从一个或多个表中获取数据的结果。视图并不存储数据本…

机器学习实战—天猫用户重复购买预测

目录 背景 数据集 用户画像数据 用户行为日志数据 训练数据 测试数据 提交数据 其它数据 数据探索 导入依赖库 读取数据 查看数据信息 缺失值分析 数据分布 复购因素分析 特征工程 模型训练 模型验证 背景 商家有时会在特定日期,例如节礼日(Boxing-day),黑…

代码随想录打卡Day29

今天的题目尊嘟好难…除了第三题没看视频,其他的题目都是看了视频才做出来的。二刷等我。 134. 加油站 感觉这道题和之前的53. 最大子序和有点像,最大子序和是一旦当前总和为负数则立即抛弃当前的总和,从下个位置重新开始计算,而…

保护您的企业免受网络犯罪分子侵害的四个技巧

在这个日益数字化的时代,小型企业越来越容易受到网络犯罪的威胁。网络犯罪分子不断调整策略,并使用人工智能来推动攻击。随着技术的进步,您的敏感数据面临的风险也在增加。 风险的不断增大意味着,做好基本工作比以往任何时候都更…

04_Python数据类型_列表

Python的基础数据类型 数值类型:整数、浮点数、复数、布尔字符串容器类型:列表、元祖、字典、集合 列表 列表(List)是一种非常灵活的数据类型,它可以用来存储一系列的元素。容器类型,能够存储多个元素的…

MybatisPlus的一点了解

1.MybatisPlus使用: (1)Serializable id 这种参数要怎么传入值,对应的底层调用和数据库表格命名和实体类映射之间有什么关系 在 Java 中,Serializable 是一个标记接口,它表示一个类的实例可以被序列化&am…

0918作业

一、整理 1)ls:查看文件信息 2)passwd:修改密码 3)cd:切换目录 4)touch:创建文件 5)mkdir:创建文件夹 6)cp:拷贝文件 7)mv&#xff1…