HarmonyOS 鸿蒙Next中swiper组件图片太多加载不出来的问题

HarmonyOS 鸿蒙Next中swiper组件图片太多加载不出来的问题

5 回复
@Entry
@Component
struct LazyImageLoadingExample {
  imageUrls: string[] = [
    'https://dummyimage.com/600x400/000/fff',
    'https://dummyimage.com/600x400/ff0/000',
    'https://dummyimage.com/600x400/0f0/fff'
  ];

  build() {
    Column({ space: 20 }) {
      LazyForEach(this.imageUrls, (url: string) => {
        ImageLazyLoad({ imageUrl: url })
      }, (url: string) => url)
    }
    .width('100%')
    .padding({ top: 20, left: 20, right: 20 })
  }
}

@Component
struct ImageLazyLoad {
  @Link imageUrl: string;
  private isImageLoaded: boolean = false;

  aboutToAppear() {
    setTimeout(() => {
      this.isImageLoaded = true;
    }, 5000);
  }

  build() {
    if (this.isImageLoaded) {
      Image(this.imageUrl)
        .width('100%')
        .height(200)
        .objectFit(ImageFit.Cover)
    } else {
        Stack({ alignContent: Alignment.Center }) {
          Text('Loading...')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
        }
       .width('100%')
       .height(200)
       .backgroundColor($r('app.color.placeholder_bg'))
    }
  }
}

更多关于HarmonyOS 鸿蒙Next中swiper组件图片太多加载不出来的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


使用layzforeach替换foerch试试

如果图片加载失败(例如URL无效),加载指示器消失,显示一个黑色的背景,中间提示"加载失败"和"无法加载该图片"的文字。

// Index.ets
import { TimeListLargeMediaComponent } from './TimeListLargeMediaComponent';

@Entry
@Component
struct Index {
  @State allMediaArray: string[] = [
    'https://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960',
    'https://img0.baidu.com/it/u=1175924242,1279975311&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
    'https://gips3.baidu.com/it/u=3886271102,3123389489&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960'
  ];

  build() {
    Swiper() {
      ForEach(this.allMediaArray, (item: string) => {
        ListItem() {
          TimeListLargeMediaComponent({ media: item })
            .height('100%')
        }
        .width('100%')
      })
    }
    .indicator(true)
    .loop(true)
    .itemSpace(0)
    .cachedCount(1)
    .width('100%')
    .height('100%')
    .backgroundColor(Color.Black)
  }
}
// TimeListLargeMediaComponent.ets
@Component
export struct TimeListLargeMediaComponent {
  @Prop media: string;
  @State isLoading: boolean = true; // 控制加载覆盖层的显示
  @State isError: boolean = false; // 控制错误覆盖层的显示

  aboutToAppear(): void {
    // 模拟加载延迟
    this.isLoading = true;
    this.isError = false;
    const delayMs = 1000; // 设置一个1000毫秒的延迟,之后才允许渲染Image
    setTimeout(() => {
      this.isLoading = false;
    }, delayMs);
  }

  build() {
    Stack({ alignContent: Alignment.Center }) {
      if (!this.isLoading && !this.isError) {
        Image(this.media)
          .objectFit(ImageFit.Contain)
          .width('100%')
          .height('100%')
          .onComplete(() => { // 绑定.onComplete回调:当图片加载成功时,将isLoading设为false,isError设为false。
            this.isLoading = false;
            this.isError = false;
          })
          .onError(() => { // 绑定.onError回调:当图片加载失败时,将isLoading设为false,isError设为true。
            this.isLoading = false;
            this.isError = true;
          }
      }

      // 获取图片数据的过程中,显示加载覆盖层
      if (this.isLoading) {
        Row() {
          this.builderLoading()
        }
        .width('100%')
        .height('100%')
        .backgroundColor(Color.Gray)
        .justifyContent(FlexAlign.Center)
        .alignItems(VerticalAlign.Center)
        .zIndex(1)
      }

      // 获取图片失败或者图片信息错误,显示错误覆盖层
      if (this.isError && !this.isLoading) {
        Column() {
          Text('加载失败')
            .fontSize(20)
            .fontColor(Color.White)
            .margin({ bottom: 10 })
          Text('无法加载该图片')
            .fontSize(16)
            .fontColor(Color.White)
        }
        .width('100%')
        .height('100%')
        .backgroundColor(Color.Black)
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Center)
        .zIndex(1)
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.Black)
  }

  // 加载动画Builder
  @Builder
  builderLoading() {
    Column({ space: 10 }) {
      LoadingProgress()
        .color(Color.White)
        .width(50)
        .height(50)
      Text('加载中...')
        .fontSize(14)
        .fontColor(Color.White)
    }
    .alignItems(HorizontalAlign.Center)
  }
}

可以试试懒加载

在HarmonyOS鸿蒙Next中,如果Swiper组件加载的图片过多导致加载不出来,通常是因为内存不足或图片资源过大。建议采取以下优化措施:

  1. 懒加载:使用lazyForEachLazyColumn实现图片的懒加载,仅在需要时加载图片。
  2. 图片压缩:对图片进行压缩,减小文件大小,降低内存占用。
  3. 分页加载:将图片分批次加载,避免一次性加载过多图片。
  4. 缓存机制:使用图片缓存库(如ImageCache)缓存已加载的图片,减少重复加载。
  5. 释放资源:在Swiper组件销毁时,手动释放图片资源,避免内存泄漏。

通过这些方法可以有效优化Swiper组件的性能,避免图片加载失败的问题。

回到顶部