【HarmonyOS NEXT 】应用开发:ArkTS瀑布流(无线滚动)示例一

SDK:5.0.0
DevEco Studio:5.0.3
Node.js:18.20.1

瀑布流容器,由“行”和“列”分割的单元格所组成,通过容器自身的排列规则,将不同大小的“项目”自上而下,如瀑布般紧密布局。 

1、示例代码

import { WaterFlowDataSource } from './WaterFlowDataSource'

@Entry
@Component
struct Index {
  // 实现IDataSource接口的对象,用于瀑布流组件加载数据
  dataSource: WaterFlowDataSource = new WaterFlowDataSource()
  // console.log(dataSource)
  // 构建界面
  build() {
    Column({ space: 4 }) {
      WaterFlow() {
        LazyForEach(this.dataSource, (item: number) => {
          FlowItem() {
            Column() {
              Text("一行数据,编号:" + item).fontSize(12).height('26')
            }.width("100%")
            .border({
              width: { left: 1, right: 1, top: 0, bottom: 1 },
              color: { left: '#e3bbbb', right: Color.Blue, top: Color.Red, bottom: Color.Green },
              style: {
                // left: BorderStyle.Dotted,
                // right: BorderStyle.Dotted,
                // top: BorderStyle.Solid,
                // bottom: BorderStyle.Dashed
              }
            })
          }
          .onAppear(() => {
            // 即将触底时提前增加数据
            if (item + 20 == this.dataSource.totalCount()) {
              for (let i = 0; i < 100; i++) {
                this.dataSource.addLastItem()
              }
            }
          })
        }, (item: string) => item)
      }
      .width('100%')
      .height('100%')
      .onReachStart(() => {
        console.info('瀑布流组件到达起始位置时触发')
      })
      .onScrollStart(() => {
        console.info('瀑布流滑动开始时触发')
      })
      .onScrollStop(() => {
        console.info('瀑布流滑动停止时触发')
      })
      .onScrollFrameBegin((offset: number, state: ScrollState) => {
        // 瀑布流开始滑动时触发
        console.info('瀑布流开始滑动时触发: ' + offset + ' state: ' + state.toString())
        return { offsetRemain: offset }
      })
    }
  }
}

onReachStart:瀑布流组件到达起始位置时触发。

onReachEnd: 瀑布流组件到底末尾位置时触发。

onScrollStart:瀑布流滑动开始时触发。手指拖动瀑布流或瀑布流的滚动条触发的滑动开始时,会触发该事件。使用Scroller滑动控制器触发的带动画的滑动,动画开始时会触发该事件。

 onScrollFrameBegin:瀑布流开始滑动时触发,事件参数传入即将发生的滑动量,事件处理函数中可根据应用场景计算实际需要的滑动量并作为事件处理函数的返回值返回,瀑布流将按照返回值的实际滑动量进行滑动。

触发该事件的条件:手指拖动WaterFlow、WaterFlow惯性划动时每帧开始时触发;WaterFlow超出边缘回弹、使用滚动控制器和拖动滚动条的滚动不会触发。

2、用IDataSource接口的对象,用于瀑布流组件加载数据,创建文件WaterFlowDataSource.ets

// 实现IDataSource接口的对象,用于瀑布流组件加载数据
export class WaterFlowDataSource implements IDataSource {
  private dataArray: number[] = []
  private listeners: DataChangeListener[] = []

  constructor() {
    for (let i = 0; i < 100; i++) {
      console.log("打印:" + i)
      this.dataArray.push(i)
    }
  }

  // 获取索引对应的数据
  public getData(index: number): number {
    return this.dataArray[index]
  }

  // 通知控制器数据重新加载
  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded()
    })
  }

  // 通知控制器数据增加
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index)
    })
  }

  // 通知控制器数据变化
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index)
    })
  }

  // 通知控制器数据删除
  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index)
    })
  }

  // 通知控制器数据位置变化
  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to)
    })
  }

  //通知控制器数据批量修改
  notifyDatasetChange(operations: DataOperation[]): void {
    this.listeners.forEach(listener => {
      listener.onDatasetChange(operations);
    })
  }

  // 获取数据总数
  public totalCount(): number {
    return this.dataArray.length
  }

  // 注册改变数据的控制器
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      this.listeners.push(listener)
    }
  }

  // 注销改变数据的控制器
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener)
    if (pos >= 0) {
      this.listeners.splice(pos, 1)
    }
  }

  // 增加数据
  public add1stItem(): void {
    this.dataArray.splice(0, 0, this.dataArray.length)
    this.notifyDataAdd(0)
  }

  // 在数据尾部增加一个元素
  public addLastItem(): void {
    this.dataArray.splice(this.dataArray.length, 0, this.dataArray.length)
    this.notifyDataAdd(this.dataArray.length - 1)
  }

  // 在指定索引位置增加一个元素
  public addItem(index: number): void {
    this.dataArray.splice(index, 0, this.dataArray.length)
    this.notifyDataAdd(index)
  }

  // 删除第一个元素
  public delete1stItem(): void {
    this.dataArray.splice(0, 1)
    this.notifyDataDelete(0)
  }

  // 删除第二个元素
  public delete2ndItem(): void {
    this.dataArray.splice(1, 1)
    this.notifyDataDelete(1)
  }

  // 删除最后一个元素
  public deleteLastItem(): void {
    this.dataArray.splice(-1, 1)
    this.notifyDataDelete(this.dataArray.length)
  }

  // 在指定索引位置删除一个元素
  public deleteItem(index: number): void {
    this.dataArray.splice(index, 1)
    this.notifyDataDelete(index)
  }

  // 重新加载数据
  public reload(): void {
    this.dataArray.splice(1, 1)
    this.dataArray.splice(3, 2)
    this.notifyDataReload()
  }
}

 在 HarmonyOS 的应用开发框架中,IDataSource 是一个接口,用于定义数据源的行为,它主要用于向 UI 组件提供数据。这个接口特别重要,因为它允许开发者以一种类型安全和灵活的方式为 UI 组件(如列表、瀑布流等)提供数据。

IDataSource 接口通常包含以下方法:

  • getCount(): 返回数据源中的项目总数。
  • getItemAt(index): 根据给定的索引返回数据源中的项目。
  • addChangeListener(listener): 添加一个数据改变监听器,当数据源中的数据发生变化时,监听器会被通知。
  • removeChangeListener(listener): 移除一个数据改变监听器。

【1】参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值