HarmonyOS NEXT边学边玩,从零开发一款影视APP(二、首页轮播图懒加载的实现)

2025-01-13 19:30:07
44次阅读
0个评论

在开发一款影视APP时,首页的轮播图是一个非常重要的部分。它不仅能够吸引用户的注意力,还能有效地推广重点内容。为了提升应用的性能和用户体验,我们可以实现轮播图的懒加载功能。本文将详细介绍如何在HarmonyOS NEXT应用开发中实现这一功能。

1. 数据源设计

开源仓库地址:https://atomgit.com/csdn-qq8864/hmmovie 在这里插入图片描述

首先,我们需要设计一个数据源类 BasicDataSource,该类会实现 IDataSource 接口,用于管理轮播图数据。以下是 BasicDataSource 的代码:

class BasicDataSource<T> implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private originDataArray: T[] = [];

  totalCount(): number {
    return this.originDataArray.length;
  }

  getData(index: number): T {
    return this.originDataArray[index];
  }

  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.slice(pos, 1);
    }
  }

  // 通知LazyForEach组件需要重新重载所有子组件
  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    })
  }

  // 通知LazyForEach组件需要在index对应索引处添加子组件
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }
}

代码解释

  • private listeners: 用于存储数据变化的监听器。
  • private originDataArray: 存储原始数据的数组。
  • totalCount: 返回数据源中数据的总数。
  • getData: 根据索引获取数据。
  • registerDataChangeListener: 注册数据变化监听器。
  • unregisterDataChangeListener: 移除数据变化监听器。
  • notifyDataReload: 通知所有监听器数据需要重新加载。
  • notifyDataAdd: 通知所有监听器在指定索引处添加了新数据。

2. 扩展数据源以支持懒加载

接下来,我们需要扩展 BasicDataSource 类来实现轮播图数据的懒加载。这里我们创建一个 SwiperDataSource 类继承自 BasicDataSource,并添加了一些懒加载相关的功能:

class SwiperDataSource<T> extends BasicDataSource<T> {
  private dataArray: T[] = [];

  totalCount(): number {
    return this.dataArray.length;
  }

  getData(index: number): T {
    return this.dataArray[index];
  }

  // 在列表末尾添加数据并通知监听器
  pushData(data: T): void {
    this.dataArray.push(data);
    this.notifyDataAdd(this.dataArray.length - 1);
  }

  // 重载数据
  reloadData(): void {
    // 不会引起状态变化
    this.dataArray = [];
    // 必须通过DataChangeListener来更新
    this.notifyDataReload();
  }
}

代码解释

  • private dataArray: 存储懒加载后的数据。
  • pushData: 向数据数组中添加新数据,并通知监听器有新数据添加。
  • reloadData: 重置数据数组,并通知监听器数据需要重新加载。

3. 实现轮播图懒加载

在设计好数据源后,我们可以开始实现轮播图。使用 SwiperLazyForEach 组件来实现懒加载。以下是首页轮播图的代码:

// 轮播图
Swiper(this.swiperController) {
  LazyForEach(this.swiperData, (item: SwiperItem) => {
    Stack({ alignContent: Alignment.Center }) {
      Image(item.imageUrl)
        .width('100%')
        .height(180)
        .zIndex(1)
        .onClick(() => {
          this.pageStack.pushDestinationByName("MovieDetailPage", { id:item.id }).catch((e:Error)=>{
            // 跳转失败,会返回错误码及错误信息
            console.log(`catch exception: ${JSON.stringify(e)}`)
          }).then(()=>{
            // 跳转成功
          });
        })

      // 显示轮播图标题
      Text(item.title)
        .padding(5)
        .margin({ top: 135 })
        .width('100%')
        .height(60)
        .textAlign(TextAlign.Center)
        .maxLines(2)
        .textOverflow({ overflow: TextOverflow.Clip })
        .fontSize(22)
        .fontColor(Color.White)
        .opacity(100)// 设置标题的透明度 不透明度设为100%,表示完全不透明
        .backgroundColor('#808080AA')// 背景颜色设为透明
        .zIndex(2)
        .onClick(() => {
          this.pageStack.pushDestinationByName("MovieDetailPage", { id:item.id }).catch((e:Error)=>{
            // 跳转失败,会返回错误码及错误信息
            console.log(`catch exception: ${JSON.stringify(e)}`)
          }).then(()=>{
            // 跳转成功
          });
        })
    }
  }, (item: SwiperItem) => item.id)
}
.cachedCount(2)
.index(1)
.autoPlay(true)
.interval(4000)
.loop(true)
.indicatorInteractive(true)
.duration(1000)
.itemSpace(0)
.curve(Curve.Linear)
.onChange((index: number) => {
  console.info(index.toString())
})
.onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {
  console.info("index: " + index)
  console.info("current offset: " + extraInfo.currentOffset)
})
.height(180) // 设置高度

代码解释

  • Swiper: 轮播图组件,通过 this.swiperController 进行控制。
  • LazyForEach: 根据数据源动态渲染子组件。this.swiperData 是数据源实例,(item: SwiperItem) => item.id 是唯一标识符生成函数。
  • Stack: 容器组件,用于将图片和标题堆叠在一起。
  • Image: 显示轮播图的图片。
  • Text: 显示图片的标题,设置了最大行数、文字溢出处理、字体大小、颜色、背景颜色等属性。
  • cachedCount: 设置缓存的子组件数量。
  • index: 设置初始显示的图片索引。
  • autoPlay: 是否自动播放。
  • interval: 自动播放的时间间隔。
  • loop: 是否循环播放。
  • indicatorInteractive: 指示器是否可交互。
  • duration: 切换动画的持续时间。
  • itemSpace: 子组件之间的间距。
  • curve: 切换动画的曲线。
  • onChange: 当轮播图切换时触发的回调函数。
  • onGestureSwipe: 当用户进行滑动操作时触发的回调函数。

4. 总结

通过本文,我们学习了如何在HarmonyOS NEXT应用开发中实现轮播图的懒加载功能。这种方法不仅提升了应用的性能,还为用户提供了更好的使用体验。你可以根据实际需求对代码进行进一步的优化和扩展,以满足更多功能的实现。希望这篇文章对你有所帮助,欢迎在评论区交流和提问。

收藏00

登录 后评论。没有帐号? 注册 一个。