🎯 案例集合List:多级列表(商品分类)

🌍 案例集合List

🚪 最近开启了学员班级点我欢迎加入

🏷️ 效果图

📖 参考

🧩 拆解

  • 多级列表滚动,头部组粘性(后续会增加高性能的方式)
import { HashMap } from "@kit.ArkTS";

/**
 * 模拟数据
 */
const mockData: string[] = ['购物', '体育', '服装', '军事']
/**
 * 多级列表数据
 */
const hasMap: HashMap<string, string[]> = new HashMap()
for (let i = 0; i < mockData.length; i++) {
  hasMap.set(`${mockData[i]}_mock`, ['吃饭', '睡觉', '打豆豆'])
}

@Component
export struct MultiLevelList {
  /**
   * 当前选中的列表项下标
   */
  @State curSelectIdx: number = 0
  /**
   * 列表构造器
   */
  private listScroller: ListScroller = new ListScroller()

  /**
   * 列表组头部
   * @param headerName
   */
  @Builder
  groupHeaderBuilder(headerName: string) {
    Row() {
      Text(headerName)
        .fontSize(18)
        .fontWeight(500)
    }
    .width('100%')
    .height(56)
    .padding({ left: 8 })
    .backgroundColor('#F1F3F5')
  }

  /**
   * 当前滑动或者点击的列表组项
   * @param index
   * @param operationType 操作类型
   */
  curSelectItemChange(index: number, operationType: string) {
    this.curSelectIdx = index

    // 只有为左边点击label的时候才需滚动右侧列表
    if (operationType === 'click') {
      this.listScroller.scrollToIndex(index)
    }
  }

  /**
   * 最后一个列表组的下的内边距 (主要处理列表组滑动到底部)
   * @param idx
   * @returns
   */
  private ednListItemGroupBottomPadding(idx: number) {
    // 单个列表组的高度 (购物为例)
    const itemGroupHeight = hasMap.get('购物_mock').length * 100
    // 表头高度 * 2
    const groupHeaderHeight = 56 * 2
    return mockData.length - 1 === idx ? itemGroupHeight + groupHeaderHeight : 0
  }

  build() {
    Row() {
      Column() {
        ForEach(mockData, (item: number, idx: number) => {
          Text(item.toString())
            .width('100%')
            .height(56)
            .fontSize(this.curSelectIdx === idx ? 20 : 16)
            .textAlign(TextAlign.Center)
            .fontColor(this.curSelectIdx === idx ? Color.Orange : Color.Black)
            .opacity(this.curSelectIdx === idx ? 1 : 0.6)
            .fontWeight(this.curSelectIdx === idx ? FontWeight.Bold : FontWeight.Normal)
            .onClick(() => {
              this.curSelectItemChange(idx, 'click')
            })
        }, (item: number) => item.toString())
      }
      .width(130)
      .height('100%')
      .backgroundColor('#4dfdddcb')

      List({ scroller: this.listScroller }) {
        ForEach(mockData, (item: string, idx: number) => {
          ListItemGroup({ header: this.groupHeaderBuilder(item), space: 5 }) {
            ForEach(hasMap.get(`${item}_mock`), (item: string) => {
              ListItem() {
                Text(item)
                  .height(100)
                  .width('100%')
                  .fontSize(20)
                  .borderRadius(10)
                  .textAlign(TextAlign.Center)
              }
            }, (item: number) => item.toString())
          }
          .padding({ bottom: this.ednListItemGroupBottomPadding(idx) })
        }, (item: number) => item.toString())
      }
      .height('100%')
      .layoutWeight(1)
      .scrollBar(BarState.Off) // 关闭滚动条
      .sticky(StickyStyle.Header) // 头部粘性
      .edgeEffect(EdgeEffect.None) // 关闭滚动动效
      .padding({ left: 8, right: 12 })
      .onScrollIndex((idx: number) => {
        this.curSelectItemChange(idx, 'swipe')
      })
    }
    .width('100%')
    .height('100%')
  }
}

🌸🌼🌺

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐