DEV Community

wei chang
wei chang

Posted on

鸿蒙Next开发入门教程-瀑布流

今天和大家分享一下瀑布流的实战案例,和官方文档略有不同,本文数据直接从api接口获取,更接近实战。需要注意的是,要实现瀑布流,接口最好将图片尺寸一起返回。网络请求使用幽蓝君封装的网络库

本文效果图:

Image description

首先要实现IDataSource接口的对象,用于瀑布流组件加载数据:

export class WaterFlowDataSource implements IDataSource {



  private dataArray: Object[] = []

  private listeners: DataChangeListener[] = []



  constructor() {

    let url = "http://youlanjihua.com/AIImage/wallpaper.php?classId=2"

    HttpManager.getInstance().request({

      method: RequestMethod.GET,

      url: url

    }).then((result:object)=>{

      let str = JSON.stringify(result)

      let strArr:Object[] =  JSON.parse(str)

      for (let i = 0; i < strArr.length; i++) {

        this.dataArray.push(strArr[i])

      }

      this.notifyDataReload()

    })



  }



  // 获取索引对应的数据

  public getData(index: number): Object {

    return this.dataArray[index]

  }



  // 通知控制器数据重新加载

  notifyDataReload(): void {

    this.listeners.forEach(listener => {

      listener.onDataReloaded()

    })

  }



  // 通知控制器数据增加

  notifyDataAdd(index: number): void {

    this.listeners.forEach(listener => {

      listener.onDataAdded(index)

    })

  }



  // 通知控制器数据变化

  notifyDataChange(index: number): void {

    this.listeners.forEach(listener => {

      listener.onDataChanged(index)



    })

  }



  // 通知控制器数据删除

  notifyDataDelete(index: number): void {

    this.listeners.forEach(listener => {

      listener.onDataDeleted(index)

    })

  }



  // 通知控制器数据位置变化

  notifyDataMove(from: number, to: number): void {



    this.listeners.forEach(listener => {

      listener.onDataMoved(from, to)

    })

  }



  // 获取数据总数

  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 Reload(): void {

    this.dataArray.splice(1, 1)

    this.dataArray.splice(3, 2)

    this.notifyDataReload()

  }

}
Enter fullscreen mode Exit fullscreen mode

然后使用WaterFlow组件展示数据:

import { HttpManager } from '../../library/httpTool/HttpManager';

import { RequestMethod } from '../../library/httpTool/RequestOptions';

import display from '@ohos.display';



@Entry

@Component

export  struct Home {

  @State dataSource: WaterFlowDataSource = new WaterFlowDataSource()

  @State item_width:number = (px2vp(display.getDefaultDisplaySync().width) - 5)/2



  build() {

      Column({ space: 2 }) {

        WaterFlow() {

          LazyForEach(this.dataSource, (item: object,index:number) => {

            FlowItem() {

              Column() {

                Image("http://youlanjihua.com/AIImage/wallpaper/compressSize/l_" + item['cover'])

                  .objectFit(ImageFit.Fill)

                  .width('100%')

                  .layoutWeight(1)

              }

            }

            .width('100%')

            .height(this.item_width * item['height']/item['width'])

            .backgroundColor('#ececec')

          }, (item: string) => item)

        }

        .columnsTemplate("1fr 1fr")

        .columnsGap(5)

        .rowsGap(5)

        .backgroundColor(Color.White)

        .width('100%')

        .height('100%')

      }

  }

}
Enter fullscreen mode Exit fullscreen mode

Heroku

Built for developers, by developers.

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly — using the tools and languages you already love!

Learn More

Top comments (0)

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay