HarmonyOS 鸿蒙Next中壁纸懒加载与保存

HarmonyOS 鸿蒙Next中壁纸懒加载与保存 如何使用 LazyForEach 优化大量壁纸的加载,并实现保存到图库?(问题来源项目案例整理:https://github.com/heqiyuan35-creator/BaitKnows.git

3 回复

实现 IDataSource 接口配合 SaveButton 安全组件:

// 1. 数据源实现
class WallpaperDataSource implements IDataSource {
  private dataArray: WallpaperItem[] = [];
  private listeners: DataChangeListener[] = [];
  totalCount(): number { return this.dataArray.length; }
  getData(index: number): WallpaperItem { return this.dataArray[index]; }
  registerDataChangeListener(listener: DataChangeListener) {
    this.listeners.push(listener);
  }
  notifyDataReload() {
    this.listeners.forEach(l => l.onDataReloaded());
  }
}

// 2. 懒加载渲染
Grid() {
  LazyForEach(this.wallpaperDataSource, (item: WallpaperItem) => {
    GridItem() { this.WallpaperCard(item) }
  }, (item) => item.id)
}
.cachedCount(4)  // 缓存4个额外项

// 3. 使用 SaveButton 保存(无需申请权限)
SaveButton({ icon: SaveIconStyle.FULL_FILLED, text: SaveDescription.SAVE_IMAGE })
  .onClick(async (event, result) => {
    if (result === SaveButtonOnClickResult.SUCCESS) {
      // 截图
      const pixelMap = await componentSnapshot.get('previewArea');
      // 编码
      const packer = image.createImagePacker();
      const buffer = await packer.packing(pixelMap, { format: 'image/jpeg', quality: 95 });
      // 保存到图库
      const helper = photoAccessHelper.getPhotoAccessHelper(context);
      const uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
      const file = fs.openSync(uri, fs.OpenMode.WRITE_ONLY);
      fs.writeSync(file.fd, buffer);
      fs.closeSync(file);
    }
  })

更多关于HarmonyOS 鸿蒙Next中壁纸懒加载与保存的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


鸿蒙Next中壁纸懒加载通过Image组件的lazyForEach或LazyForEach组件实现,仅当组件进入视口时加载资源,节省内存。保存壁纸使用媒体库管理接口(如@ohos.file.mediaLibrary),通过getPublicDirectory获取路径,再调用createAssetwrite方法将图片写入指定目录。

在HarmonyOS Next中,使用LazyForEach优化壁纸列表加载并实现保存到图库,核心在于结合ArkUI的声明式开发与异步任务管理。以下是关键实现方案:

1. 壁纸懒加载优化

  • 数据源与LazyForEach:将壁纸数据封装为ImageData[]数组,并包装进ImageDataSource类,实现IImageDataSource接口。在UI中使用LazyForEach动态创建列表项,仅渲染可视区域内的壁纸图片,避免一次性加载全部资源导致的性能问题。
  • 图片加载策略:结合Image组件的syncLoad属性或onComplete回调,可控制图片的同步/异步加载模式。对于网络壁纸,建议使用Imagealt属性设置占位图,并通过异步任务加载实际图片资源。

2. 保存壁纸到图库

  • 权限声明:在module.json5中配置ohos.permission.READ_IMAGEVIDEOohos.permission.WRITE_IMAGEVIDEO权限。
  • 媒体库接口调用:通过[@ohos](/user/ohos).file.picker选择保存路径,再使用[@ohos](/user/ohos).file.fs将壁纸文件写入目标位置。若壁纸为网络资源,需先通过[@ohos](/user/ohos).request下载到应用缓存目录,再转移至媒体库。
  • 异步保存示例
    import picker from '[@ohos](/user/ohos).file.picker';
    import fs from '[@ohos](/user/ohos).file.fs';
    
    async function saveToGallery(imageUri: string) {
      const saveOptions = new picker.PhotoSaveOptions();
      saveOptions.newFileNames = ['wallpaper.jpg'];
      const photoSave = picker.createPhotoSavePicker();
      const fileUri = await photoSave.save(saveOptions);
      
      // 将imageUri对应的文件复制到fileUri
      await fs.copyFile(imageUri, fileUri);
    }
    

3. 性能与体验优化

  • 内存管理:LazyForEach在列表项滑出视窗后会自动销毁组件,但需注意在ImageData中及时释放不再使用的图片资源句柄。
  • 保存状态反馈:保存操作应封装为异步任务,配合Loading组件或PromptAction.toast提示用户操作结果,避免阻塞UI线程。

通过以上方案,可有效平衡大量壁纸的加载性能与保存功能完整性。具体实现细节可参考你提供的项目案例中的资源管理模块。

回到顶部