鸿蒙HarmonyOS开发知识:Waterflow组件布局

 背景

当我们浏览购物应用时,比如某宝,某书,会发现浏览的布局都是错落有致的,如图:

这个对应HarmonyOS应用开发就需要我们用到WaterFlow组件,本篇我们就此组件进行介绍。

WaterFlow组件介绍

1,WaterFlow是容器组件,内部分裂成行和列形式,通过容器自身的排列规则,将不同大小的“项目”自上而下,如瀑布般紧密布局。

该组件从API Version 9开始支持。官方doc地址:https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-container-waterflow-0000001582933637-V3

简单解读

  • 接口

    WaterFlow(options?: {footer?: CustomBuilder, scroller?: Scroller})
    
    参数名参数类型必填参数描述
    footerCustomBuilder设置WaterFlow尾部组件。
    scrollerScroller可滚动组件的控制器,与可滚动组件绑定。目前瀑布流仅支持Scroller组件的scrollToIndex接口。
  • 属性

    名称参数类型描述
    columnsTemplatestring设置当前瀑布流组件布局列的数量,不设置时默认1列。例如, ‘1fr 1fr 2fr’ 是将父组件分3列,将父组件允许的宽分为4等份,第一列占1份,第二列占1份,第三列占2份。并支持auto-fill。默认值:‘1fr’
    rowsTemplatestring设置当前瀑布流组件布局行的数量,不设置时默认1行。例如, '1fr 1fr 2fr’是将父组件分三行,将父组件允许的高分为4等份,第一行占1份,第二行占一份,第三行占2份。并支持auto-fill。默认值:‘1fr’
    itemConstraintSizeConstraintSizeOptions设置约束尺寸,子组件布局时,进行尺寸范围限制。
    columnsGapLength设置列与列的间距。默认值:0
    rowsGapLength设置行与行的间距。默认值:0
    layoutDirectionFlexDirection设置布局的主轴方向。默认值:FlexDirection.Column

    layoutDirection优先级高于rowsTemplate和columnsTemplate。根据layoutDirection设置情况,分为以下三种设置模式:

    • layoutDirection设置纵向布局(FlexDirection.Column 或 FlexDirection.ColumnReverse)

      此时columnsTemplate有效(如果未设置,取默认值)。例如columnsTemplate设置为"1fr 1fr"、rowsTemplate设置为"1fr 1fr 1fr"时,瀑布流组件纵向布局,辅轴均分成横向2列。

    • layoutDirection设置横向布局(FlexDirection.Row 或 FlexDirection.RowReverse)

      此时rowsTemplate有效(如果未设置,取默认值)。例如columnsTemplate设置为"1fr 1fr"、rowsTemplate设置为"1fr 1fr 1fr"时,瀑布流组件横向布局,辅轴均分成纵向3列。

    • layoutDirection未设置布局方向

      布局方向为layoutDirection的默认值:FlexDirection.Column,此时columnsTemplate有效。例如columnsTemplate设置为"1fr 1fr"、rowsTemplate设置为"1fr 1fr 1fr"时,瀑布流组件纵向布局,辅轴均分成横向2列。

  • 事件

    名称功能描述
    onReachStart(event: () => void)瀑布流组件到达起始位置时触发。
    onReachEnd(event: () => void)瀑布流组件到底末尾位置时触发。

代码示例

export class DataInfo {
  type!:string
  src!:string
  color!:string
}

// 实现IDataSource接口的对象,用于瀑布流组件加载数据
export class WaterFlowDataSource implements IDataSource {
  private listeners: DataChangeListener[] = []
  private bcolor: string[] = [
    "#E29C45","#896C39","#D9B611","#BDDD22","#C9DD22","#AFDD22",
"#789262","#A3D900","#9ED900","#0EB83A","#0AA344","#00BC12","#0C8918","#1BD1A5",
"#2ADD9C","#48C0A3","#3DE1AD","#40DE5A","#9D2933","#BF242A","#FF4777","#FF461F",
"#F36838","#FFB61E","#FFC64B","#E9BB1D","#845A33","#16A951","#1685A9","#003472",
"#FFF2DF","#FFB3A7","#ED5736","#F00056","#F47983","#DB5A6B","#F20C00","#C93756",
"#F05654","#FF2121","#8C4356","#C83C23","#FF4C00","#FF4E20","#F35336","#CB3A56",
"#FF2D51","#C91F37","#EF7A82","#FF0097","#FF3300","#C3272B","#A98175","#C32136",
"#B36D61",  ]

  // 获取索引对应的数据
  public getData(index: number): DataInfo {
    {
      let bcin = index%50
      return { type: "img", src: "autoimage" + index + ".jpg", color: this.bcolor[bcin]}
    }
  }

  // 获取数据总数
  public totalCount(): number {
    return 100
  }

  // 注册改变数据的控制器
  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)
    }
  }
}

@Entry
@Component
struct Index {
  @State message: string = 'WaterFlow'
  datasource: WaterFlowDataSource = new WaterFlowDataSource()
  @Builder itemFoot() {
    Column() {
      Text(`Footer`)
        .fontSize(50)
        .textAlign(TextAlign.Center)
        .backgroundColor("#F0F0F4")
        .width("100%")
        .height(150)
        .align(Alignment.Center)
        .margin({ top: 2 })
    }
  }

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(30)
          .fontWeight(FontWeight.Bold)
        Row() {
          WaterFlow({footer: this.itemFoot.bind(this)}) {
            LazyForEach(this.datasource, (item:DataInfo, idx:number) => {
              FlowItem() {
                Column() {
                  Text(`${item.type}${idx}`).fontSize(32).height('32').width('100')
                  if (idx % 4 == 0) {
                    Image($rawfile(item.src)).objectFit(ImageFit.Fill).height(100)
                  } else if (idx % 4 == 1) {
                    Image($rawfile(item.src)).objectFit(ImageFit.Fill).height(200)
                  } else if (idx % 4 == 2) {
                    Image($rawfile(item.src)).objectFit(ImageFit.Fill).height(240)
                  } else if (idx % 4 == 3) {
                    Image($rawfile(item.src)).objectFit(ImageFit.Fill).height(280)
                  }
                }.backgroundColor(item.color)
              }
              .width('100%')
            })
          }
          .alignSelf(ItemAlign.Center)
          .columnsTemplate('1fr 1fr 1fr')
          .layoutDirection(FlexDirection.Column)
          .columnsGap(12)
          .rowsGap(12)
          .height('100%')
          .width('100%')
          .padding({ left: 12, right: 12, top: 12, bottom: 12 })
          .backgroundColor(Color.White)
          .onReachEnd(() => {
            console.info("onReachEnd")
          })
        }.width('100%')
      }
      .width('100%')

    }
    .height('100%')
  }
}
  • 如果你觉得这篇内容对你还蛮有帮助
  • 想要获取更多完整鸿蒙最新学习知识点,请移步前往小编::(鸿蒙Next学习资料)
  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值