写点什么

鸿蒙 Next Scroll+List+Tabs 实现关联滑动

作者:auhgnixgnahz
  • 2025-06-23
    北京
  • 本文字数:1737 字

    阅读完需:约 6 分钟

实现一个 Scroll 嵌套 List+Tabs,Tabs 实现吸顶效果,Tabs 标签可以随着 List 的滑动自动切换,切换 Tabs 标签时可以自动定位 List 位置。


实现思路:


1.滑动事件处理,Scroll 嵌套 List,向上滑动优先父容器滑动,向下滑动优先 List 滑动,滑动事件处理在绑定半模态页面那篇有介绍


2.Tabs 吸顶,使用 Column 包裹 Tabs+List,高度设置为屏幕高度,向上滑动时,Tabs 就固定到顶部


3.Tabs 和 List 关联滑动,需要监听 Tabs 的 onChange 事件,获取到点击 Tab 时的回调去控制 List 的滑动,监听 List 的 onScrollIndex 事件,获取到当前最上面的 item 的索引,根据业务需求去切换到指定的 Tab


实现效果如下:



@Entry@Componentstruct NestedScroll {  @State arr: number[] = []  @State selectedIndex: number = 0  private controller: TabsController = new TabsController()  private listScroller: ListScroller = new ListScroller()  //样式封装,可以看一下我之前发的组件样式封装文章  @Styles  listCard() {    .backgroundColor(Color.White)    .height(72)    .width("100%")    .borderRadius(12)  }  //Tabs的简单使用可以查看之前的文章  tabs: string[] = ['生活服务', '办公必备', '出行出差'];  @Builder  tabBuilder(index: number, name: string) {    Column() {      Text(name)        .fontColor(this.selectedIndex === index ? '#007DFF' : '#182431')        .fontSize(16)        .fontWeight(this.selectedIndex === index ? 500 : 400)        .lineHeight(22)        .margin({ top: 17, bottom: 7 })      Divider()        .strokeWidth(2)        .width(20)        .margin({bottom:15})        .color('#007DFF')        .opacity(this.selectedIndex === index ? 1 : 0)    }.width(81)  }
build() { Scroll() { Column() { Text("Scroll Area") .width("100%") .height("40%") .backgroundColor('#0080DC') .textAlign(TextAlign.Center) Column() { Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { ForEach(this.tabs, (item: string, index: number) => { TabContent() { }.tabBar(this.tabBuilder(index, item)) }) }.height('auto') .onChange((index: number) => { // currentIndex控制TabContent显示页签 this.selectedIndex = index if (index==0) { this.listScroller.scrollToIndex(0) }else if (index==1){ this.listScroller.scrollToIndex(10) }else { this.listScroller.scrollToIndex(20) } }) List({ space: 10 ,scroller:this.listScroller}) { ForEach(this.arr, (item: number) => { ListItem() { Text("item" + item) .fontSize(16) }.listCard() }, (item: string) => item) }.width("100%") .edgeEffect(EdgeEffect.Spring) .nestedScroll({ scrollForward: NestedScrollMode.PARENT_FIRST, scrollBackward: NestedScrollMode.SELF_FIRST }) .onScrollIndex((start: number, end: number, center: number) => { if (start<10) { this.selectedIndex=0; }else if (start>=10&&start<20){ this.selectedIndex=1; }else { this.selectedIndex=2; } }) }.height('100%')
}.width("100%") } .edgeEffect(EdgeEffect.Spring) .friction(0.6) .backgroundColor('#DCDCDC') .scrollBar(BarState.Off) .width('100%') .height('100%') } aboutToAppear() { for (let i = 0; i < 30; i++) { this.arr.push(i) } }}
复制代码


发布于: 刚刚阅读数: 2
用户头像

auhgnixgnahz

关注

还未添加个人签名 2018-07-10 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙Next Scroll+List+Tabs实现关联滑动_鸿蒙Next_auhgnixgnahz_InfoQ写作社区