鸿蒙实现可以上下左右滑动的表格-摆脱大量ListScroller

鸿蒙实现可以上下左右滑动的表格-摆脱大量ListScroller

前言: 好久没写过文章了,最近在开发鸿蒙项目,于是乎想简单记录一下开发过程中遇到的一些好玩的东西或者经常会遇到的功能开发。

开发过程中经常遇到需要做可以上下左右滑动的类型的表格的实现,写之前也在华为论坛搜索了下相关的,官方文档提供了一种方案,创建了大量的ListScroller,个人感觉数据量大了就不是很好用,这里提供一种自己实现的方案

鉴于这个功能难度不是很大,仅仅就是布局和联动的实现,所以代码很少

效果

废话不多说,先上效果

由于CSDN上传gif失败,这里使用之前flutter 实现可以上下左右滑动的表格中的效果,和鸿蒙是一模一样的

布局

根据表格滑动的结构,可以看到布局结构如下,分别是横向滑动的标题,横向滑动的内容和上下滑动的标题+内容。

完整代码如下

ts 复制代码
@Entry
@ComponentV2
struct Index {
  leftWidth: number = 140
  cellWidth: number = 120
  cellHeight: number = 60
  titleHeight: number = 50
  private titleScroller: Scroller = new Scroller()
  private contentScroller: Scroller = new Scroller()
  private leftScroller: Scroller = new Scroller()
  private rightScroller: Scroller = new Scroller()
  titleList: string[] = []
  leftData: string[] = []
  rightData: string[] = []

  aboutToAppear(): void {
    for (let index = 0; index < 20; index++) {
      this.titleList.push(`标题${index}`)
    }
    for (let index = 0; index < 100; index++) {
      this.leftData.push(`左侧${index}`)
      this.rightData.push(`右侧行${index}`)
    }

  }

  build() {
    Column() {
      Row() {
        Text('标题').width(this.leftWidth).height(this.titleHeight).padding({ left: 16 })
        Scroll(this.titleScroller) {
          Row() {
            ForEach(this.titleList, (item: string) => {
              Text(item).width(this.cellWidth).height(this.titleHeight)
            })
          }
        }
        .layoutWeight(1)
        .scrollBar(BarState.Off)
        .edgeEffect(EdgeEffect.None)
        .scrollable(ScrollDirection.Horizontal)
        .onScrollFrameBegin((offset: number) => {
          this.contentScroller.scrollTo({
            xOffset: this.titleScroller.currentOffset().xOffset + offset,
            yOffset: 0,
            animation: false
          })
          return { offsetRemain: offset }
        })
      }.height(this.titleHeight)

      Column() {
        Row() {
          List({ scroller: this.leftScroller }) {
            Repeat<ESObject>(this.leftData).virtualScroll().each((ri: RepeatItem<ESObject>) => {
              ListItem() {
                Text(ri.item)
              }
              .height(this.cellHeight)
              .width(this.leftWidth)
              .itemBorder()
              .align(Alignment.Start)
              .padding({ left: 16 })
            })
            ListItem().height(this.cellHeight)
          }
          .width(this.leftWidth)
          .enableScrollInteraction(true)
          .scrollBar(BarState.Off)
          .edgeEffect(EdgeEffect.None)
          .cachedCount(20)
          .onScrollFrameBegin((offset: number) => {
            this.rightScroller.scrollTo({
              xOffset: 0,
              yOffset: this.leftScroller.currentOffset().yOffset + offset,
              animation: false
            })
            return ({ offsetRemain: offset })
          })

          Column() {
            Scroll(this.contentScroller) {
              List({ scroller: this.rightScroller }) {
                Repeat<string>(this.rightData).virtualScroll().each((ri: RepeatItem<ESObject>) => {
                  ListItem() {
                    Row() {
                      ForEach(this.titleList, (item: string, index: number) => {
                        Text(`${ri.item}列${index}`).width(this.cellWidth).height(this.cellHeight)
                      })
                    }
                  }.height(this.cellHeight).itemBorder()
                })
                ListItem().height(this.cellHeight)
              }
              .cachedCount(20)
              .enableScrollInteraction(true)
              .scrollBar(BarState.Off)
              .edgeEffect(EdgeEffect.None)
              .onScrollFrameBegin((offset: number) => {
                this.leftScroller.scrollTo({
                  xOffset: 0,
                  yOffset: this.rightScroller.currentOffset().yOffset + offset,
                  animation: false
                })
                return ({ offsetRemain: offset })
              })

            }
            .scrollBar(BarState.Off)
            .edgeEffect(EdgeEffect.None)
            .scrollable(ScrollDirection.Horizontal)
            .onScrollFrameBegin((offset: number) => {
              if (!this.contentScroller.isAtEnd()) {
                this.titleScroller.scrollTo({
                  xOffset: this.contentScroller.currentOffset().xOffset + offset,
                  yOffset: 0,
                  animation: false
                })
              }
              return { offsetRemain: offset }
            })
          }.layoutWeight(1)
        }
      }
    }
    .height('100%')
    .width('100%')
  }
}

@Styles
function itemBorder() {
  .border({
    color: '#cccccc',
    width: {
      left: 0,
      top: 0,
      right: 0,
      bottom: 1
    }
  })
}
相关推荐
m0_685535089 小时前
监控广角镜头架构选择
华为·光学·光学设计·光学工程·镜头设计
柒儿吖11 小时前
纯脚本项目的跨平台适配方法论:getoptions在开源鸿蒙PC平台的实现解析
华为·开源·harmonyos
搬砖的kk12 小时前
基于Flutter开发应用如何快速适配HarmonyOS
flutter·华为·harmonyos
码灵12 小时前
鸿蒙(HarmonyOS)开发板是否能够运行 Java 应用?
harmonyos
音浪豆豆_Rachel14 小时前
Flutter 与原生通信的桥梁:深入解析 Pigeon 与后台线程通信
flutter·harmonyos
音浪豆豆_Rachel14 小时前
Flutter跨平台通信的智能配置:Pigeon注解配置与鸿蒙生态深度集成
flutter·华为·harmonyos
Yeats_Liao17 小时前
MindSpore开发之路(八):数据处理之Dataset(上)——构建高效的数据流水线
数据结构·人工智能·python·机器学习·华为
FrameNotWork18 小时前
HarmonyOS 教学实战(六):复杂表单与校验体系(把“最难写”的模块写优雅)
华为·harmonyos
HMS Core18 小时前
【FAQ】HarmonyOS SDK 闭源开放能力 — Form Kit
华为·harmonyos
IT充电站20 小时前
鸿蒙应用开发之鸿蒙沙箱文件如何存媒体库?
harmonyos