欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【鸿蒙 HarmonyOS NEXT】组件嵌套滚动:nestedScroll

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

2025/10/27 18:38:40 来源:https://blog.csdn.net/weixin_71403100/article/details/142343154  浏览:    关键词:【鸿蒙 HarmonyOS NEXT】组件嵌套滚动:nestedScroll

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

✨踩坑不易,还希望各位大佬支持一下,在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自身和父组件同时滚动,自身和父组件都到达边缘以后,如果自身有边缘效果,则自身触发边缘效果,否则父组件触发边缘效果。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词