HarmonyOS 多列表滚动横向纵向联动,如汽车参数对比、股票信息列表,有无参考的示例?

如题:HarmonyOS 多列表滚动横向纵向联动,如汽车参数对比、股票信息列表,有无参考的示例?

阅读 543
1 个回答

参考示例:

// Index.ets
import AllFunds from '../view/AllFunds'

@Entry
@Component
struct Index {
  build() {
    Column({ space: 5 }) {
      Column() {
        Tabs({ barPosition: BarPosition.Start, index: 0 }) {
          TabContent() {
            AllFunds()
          }.tabBar(new SubTabBarStyle('全部基金'))

          TabContent() {
            Column().width('100%').height('100%').backgroundColor(Color.Yellow)
          }.tabBar(new SubTabBarStyle('只有'))

          TabContent() {
            Column().width('100%').height('100%').backgroundColor(Color.Blue)
          }.tabBar(new SubTabBarStyle('新建分组'))
        }
        .vertical(false)
        .scrollable(true)
        .barMode(BarMode.Fixed)
        .width('100%')
        .backgroundColor(0xF1F3F5)
      }.width('100%').height('100%')
    }
  }
}
// AllFunds.ets
import StringUtils from '../utils/StringUtils'

@Component
export default struct AllFunds {
  @State fundName: Array<string> =
    ['标题名称','标题名称','标题名称','标题名称','标题名称']
  fundsScroller = new Scroller();
  horizontalScroller = new Scroller();
  verticalScroller = new Scroller();
  data: Array<number | string> = ['10.58亿', '-1.75%', '+4.24%', '-1.75%', '-7.63%', '+1.24%']
  // data: Array<number | string> = [100, 101, 102, 103, 104, 105]
  arr: number[] = []
  classificationNames: Array<string> = ['估值', '添加后收益', '近1周', '近1月', '近3月', '近1年']

  aboutToAppear() {
    for (let index = 0; index < this.fundName.length; index++) {
      this.arr.push(index)
    }
  }

  @Builder
  itemBuilder(msg: string, curHeight: Length = 200, curWidth: Length = 100,
    curBackgroundColor: ResourceColor = '#98FB98', curFontColor: ResourceColor = Color.Black) {
    Row() {
      Column() {
        Text(msg)
          .width(curWidth)
          .height(curHeight)
          .fontSize(16)
          .textAlign(TextAlign.Center)
          .backgroundColor(curBackgroundColor)
          .fontColor(curFontColor)
        Divider()
          .strokeWidth(2)
          .color(0xFFFFFF)
      }.width(curWidth)

      Divider()
        .vertical(true)
        .strokeWidth(2)
        .color(0xFFFFFF)
        .height(curHeight)
    }
  }

  build() {

    Row() {
      Scroll(this.fundsScroller) {
        Column() {
          List({ space: 0, initialIndex: 2 }) {
            ForEach(this.fundName, (item: string, index: number) => {
              ListItem() {
                if (index == 0) {
                  // 标题
                  this.itemBuilder(item, 50, '100%', '#F8F8FF')
                } else {
                  // 基金名称
                  this.itemBuilder(item, 200, '100%', '#F8F8FF')
                }
              }
            }, (item: string) => JSON.stringify(item))
          }
          .listDirection(Axis.Vertical)
          .edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果
        }
      }
      .width('40%')
      .backgroundColor('#F8F8FF')
      .scrollBar(BarState.Off)
      .onScroll(() => {
        // 同步垂直位移量
        this.verticalScroller.scrollTo({ xOffset: 0, yOffset: this.fundsScroller.currentOffset().yOffset })
      })

      Column() {
        Scroll(this.horizontalScroller) {
          Scroll(this.verticalScroller) {
            Column() {
              ForEach(this.arr, (_temp: number, index: number) => {
                Row() {
                  if (index == 0) {
                    // 分类标题
                    ForEach(this.classificationNames, (item: string) => {
                      this.itemBuilder(item, 50, 100, '#F8F8FF')
                    }, (item: number) => JSON.stringify(item))
                  } else {
                    // 具体数据
                    ForEach(this.data, (item: number | string) => {
                      this.itemBuilder(`${item}`, 200, 100, '#98FB98',
                        StringUtils.isPositive(`${item}`) ? Color.Red : Color.Green)
                    }, (item: number | string, index: number) => JSON.stringify(`${item}_${index}`))
                  }
                }
              }, (item: string) => item)
            }
          }
          .scrollable(ScrollDirection.Vertical)
          .height('100%')
          .width(this.classificationNames.length * 100)
          .onScroll(() => {
            this.fundsScroller.scrollTo({ xOffset: 0, yOffset: this.verticalScroller.currentOffset().yOffset })
          })
        }
        .scrollable(ScrollDirection.Horizontal)
      }
      .width('60%')
      .height('100%')
      .backgroundColor('#BBFFFF')
    }
    .height('100%')
    .width('100%')
  }
}
// StringUtils.ts
function isPositive(s: string): boolean {
  const floatRegex = /^\+?(0|[1-9]\d*)(\.\d+)?[%\u4e00-\u9fa5]?$/;
  return floatRegex.test(s);
}

export default {
  isPositive,
}