HarmonyOS 鸿蒙Next开发案例 实现列表二级联动

HarmonyOS 鸿蒙Next开发案例 实现列表二级联动

场景介绍

列表的二级联动(Cascading List)是指根据一个列表(一级列表)的选择结果,来更新另一个列表(二级列表)的选项。这种联动可以使用户根据实际需求,快速定位到想要的选项,提高交互体验。例如,短视频中拍摄风格的选择、照片编辑时的场景的选择,本文即为大家介绍如何开发二级联动。

效果呈现

本例最终效果如下:

GIF

运行环境

本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:

  • IDE: DevEco Studio 3.1.1 Release
  • SDK: 3.1.0(API 9)

实现思路

  • 数字标题(titles)以及下方的数字列表(contents)分组展示:通过两个List组件分别承载数字标题和数字项。
  • 滚动数字列表,上方数字标题也随之变动:通过List组件的onScrollIndex事件获取到当前滚动数字的索引,根据该索引计算出对应标题数字的索引,然后通过Scroller的scrollToIndex方法跳转到对应的数字标题,且通过Line组件为选中的标题添加下划线。
  • 点击数字标题,下方的数字列表也随之变化:首先获取到点击数字标题的索引,通过该索引计算出下方对应数字的起始项索引,然后通过scroller的scrollToIndex方法跳转到对应索引的数字项。

开发步骤

第一步

构建列表数据,在records中记录数字列表中各个数字的首项索引值,具体代码块如下:

@State typeIndex: number = 0
private tmp: number = 0
private titles: Array<string> = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
private contents: Array<string> = ["1", "1", "1", "1", "1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "3"
    , "3", "3", "3", "3", "4", "4", "4", "5", "5", "5", "5", "5", "6", "7", "7", "7", "7", "7", "7", "7", "7", "7", "7", "7",
    "8", "8", "8", "8", "8", "9", "9", "9", "9", "9", "9", "9", "9", "9", "9", "9"]
private records: Array<number> = [0, 9, 21, 26, 29, 34, 35, 47, 52, 63]
private classifyScroller: Scroller = new Scroller();
private scroller: Scroller = new Scroller();

数字标题列表:具体代码块如下:

build() {
  Column({ space: 0 }) {
    List  ({ space: 50, scroller: this.classifyScroller, initialIndex: 0 }) {
      ForEach(this.titles, (item, index) => {
        ListItem() {
          Column() {
            Text(item)
              .fontSize(14)
            if (this.typeIndex == index) {
              Line()
                .width(item.length === 2 ? 25 : item.length === 3 ? 35 : 50)
                .height(3)
                .strokeWidth(20)
                .strokeLineCap(LineCapStyle.Round)
                .backgroundColor('#ffcf9861')
            }
          }
          .onClick(() => {
            this.typeIndex = index
            this.classifyScroller.scrollToIndex(index)
            let itemIndex = this.findItemIndex(index)
            console.log("移动元素:" + itemIndex)
            this.scroller.scrollToIndex(itemIndex)
          })
        }
      })
    }
    .listDirection(Axis.Horizontal)
    .height(50)
  }
}

数字列表,具体代码块如下:

List({ space: 20, scroller: this.scroller }) {
  ForEach(this.contents, (item, index) => {
    ListItem() {
      Column({ space: 5 }) {
        Text(item)
          .fontSize(12)
      }
      .width(60)
      .height(60)
      .backgroundColor(this.colors[item-1])
      .justifyContent(FlexAlign.Center)
      .onClick(() => {
        this.scroller.scrollToIndex(index)
      })
    }
  })
}
.listDirection(Axis.Horizontal) //列表排列方向水平
.edgeEffect(EdgeEffect.None) //不支持滑动效果

第二步

数字标题的索引值判断,根据当前滚动数字的首项索引值计算出数字标题的索引,具体代码块如下:

findClassIndex(ind: number) { // 当前界面最左边图的索引值ind
  let ans = 0
  for (let i = 0; i < this.records.length; i++) { 
    if (ind >= this.records[i] && ind < this.records[i + 1]) {
      ans = i
      break
    }
  }
  return ans
}

findItemIndex(ind: number) { 
  return this.records[ind]
}

通过Line组件构成标题下滑线,具体代码块如下:

if (this.typeIndex == index) {
  Line()
    .width(item.length === 2 ? 25 : item.length === 3 ? 35 : 50)
    .height(3)
    .strokeWidth(20)
    .strokeLineCap(LineCapStyle.Round)
    .backgroundColor('#ffcf9861')
}

第三步

点击数字标题,数字列表随之滑动:首先获取到点击数字标题的索引,通过该索引计算出下方对应数字的起始项索引,然后通过scroller的scrollToIndex方法跳转到对应索引的数字项,具体代码块如下:

.onClick(() => {
  this.typeIndex = index
  this.classifyScroller.scrollToIndex(index)
  let itemIndex = this.findItemIndex(index)
  console.log("移动元素:" + itemIndex)
  this.scroller.scrollToIndex(itemIndex)
})

第四步

数字列表的滑动或点击导致数字标题的变动:通过List组件中onScrollIndex事件获取的到屏幕中最左边数字的索引值start,然后通过该索引值计算出对应的数字标题的索引currentClassIndex,然后通过scrollToIndex控制数字标题跳转到对应索引处,具体代码块如下:

.onScrollIndex((start) => {
  let currentClassIndex = this.findClassIndex(start)
  console.log("找到的类索引为: " + currentClassIndex)
  if (currentClassIndex != this.tmp) {
    this.tmp = currentClassIndex
    console.log("类别移动到索引: " + currentClassIndex)
    this.typeIndex = currentClassIndex
    this.classifyScroller.scrollToIndex(currentClassIndex)
  }
})

更多关于HarmonyOS 鸿蒙Next开发案例 实现列表二级联动的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

有个现象:当你的[8]和[9]标题中只有两个对象的时候,从[1]标题跳到[9]标题,跳不过去

更多关于HarmonyOS 鸿蒙Next开发案例 实现列表二级联动的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


姓名: 张三
职位: 软件工程师
简介: 拥有超过10年的软件开发经验,擅长Java和Python。

回到顶部