diff --git a/CHANGELOG.md b/CHANGELOG.md index 915495b..e71b23c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - 新增putCache写入缓存接口 - 修复入参为pixelMap图片不显示问题 - 网络请求减少拼接操作,修复网络加载速度慢 +- 提供图片加载成功/失败的事件 ## 3.0.0-rc.3 - 将请求默认并行从64调整到8,减少对taskpool execute内存消耗 diff --git a/README.md b/README.md index 40972e0..4396581 100644 --- a/README.md +++ b/README.md @@ -152,24 +152,25 @@ ImageKnifeComponent({ ImageKnifeOption: ### ImageKnifeOption参数列表 -| 参数名称 | 入参内容 | 功能简介 | -|-----------------------|--------------------------------|-----------------| -| loadSrc | string、PixelMap、Resource | 主图展示 | -| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) | -| errorholderSrc | PixelMap、Resource | 错误图展示(可选) | -| objectFit | ImageFit | 主图填充效果(可选) | -| placeholderObjectFit | ImageFit | 占位图填充效果(可选) | -| errorholderObjectFit | ImageFit | 错误图填充效果(可选) | -| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) | -| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) | -| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | Resource | 错误占位图数据源 | -| border | BorderOptions | 边框圆角(可选) | -| priority | taskpool.Priority | 加载优先级(可选) | -| context | common.UIAbilityContext | 上下文(可选) | -| progressListener | (progress: number)=>void | 进度(可选) | -| signature | String | 自定义缓存关键字(可选) | -| headerOption | Array | 设置请求头(可选) | -| transformation | PixelMapTransformation | 图片变换(可选) | +| 参数名称 | 入参内容 | 功能简介 | +|-----------------------|---------------------------------------------------|-----------------| +| loadSrc | string、PixelMap、Resource | 主图展示 | +| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) | +| errorholderSrc | PixelMap、Resource | 错误图展示(可选) | +| objectFit | ImageFit | 主图填充效果(可选) | +| placeholderObjectFit | ImageFit | 占位图填充效果(可选) | +| errorholderObjectFit | ImageFit | 错误图填充效果(可选) | +| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) | +| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) | +| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | Resource | 错误占位图数据源 | +| border | BorderOptions | 边框圆角(可选) | +| priority | taskpool.Priority | 加载优先级(可选) | +| context | common.UIAbilityContext | 上下文(可选) | +| progressListener | (progress: number)=>void | 进度(可选) | +| signature | String | 自定义缓存关键字(可选) | +| headerOption | Array | 设置请求头(可选) | +| transformation | PixelMapTransformation | 图片变换(可选) | +| onLoadListener | onLoadSuccess: (data: string | PixelMap | undefined) => void、onLoadFailed: (err: string) => void| 监听图片加载成功与失败 | ### ImageKnife接口 diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 34c003f..4593079 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -108,6 +108,12 @@ struct Index { }) + Button('测试图片加载成功/失败事件').margin({top:10}).onClick(()=>{ + router.push({ + uri: 'pages/LoadStatePage', + }) + }) + } .width('100%') diff --git a/entry/src/main/ets/pages/LoadStatePage.ets b/entry/src/main/ets/pages/LoadStatePage.ets new file mode 100644 index 0000000..6f7590b --- /dev/null +++ b/entry/src/main/ets/pages/LoadStatePage.ets @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ImageKnifeComponent, ImageKnifeOption } from "@ohos/imageknife" +import matrix4 from '@ohos.matrix4' + +@Entry +@Component +struct LoadStatePage { + @State matrix1: object = matrix4.identity().scale({ x: 1, y: 1 }) + @State ImageKnifeOption: ImageKnifeOption = { + loadSrc: $r("app.media.rabbit"), + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadFailed: (err) => { + console.error("Load Failed Reason: " + err); + }, + onLoadSuccess: (data) => { + return data; + }, + }, + border: { radius: 50 } + } + + build() { + Column() { + Text('测试失败场景请先关闭网络,并保证本地没有此网络图片的缓存') + .margin({ top: 20 }) + Row() { + Button('测试失败/成功场景') + .onClick(() => { + this.ImageKnifeOption = { + loadSrc: "https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png", + placeholderSrc: $r("app.media.loading"), + errorholderSrc: $r("app.media.app_icon"), + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadFailed: (err) => { + console.error("Load Failed Reason: " + err); + }, + onLoadSuccess: (data) => { + console.info("Load Successful: " + data); + return data; + }, + }, + border: { radius: 50 } + } + }) + } + .margin({ top: 20 }) + + ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(200).width(200) + .transform(this.matrix1) + .margin({ top: 20 }) + + } + + .width('100%') + .height('100%') + } +} \ No newline at end of file diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json index 4448677..bfefb27 100644 --- a/entry/src/main/resources/base/profile/main_pages.json +++ b/entry/src/main/resources/base/profile/main_pages.json @@ -14,6 +14,7 @@ "pages/TestHeader", "pages/ImageTransformation", "pages/ObjectFitPage", - "pages/TestWriteCacheStage" + "pages/TestWriteCacheStage", + "pages/LoadStatePage" ] } \ No newline at end of file diff --git a/library/src/main/ets/ImageKnifeDispatcher.ets b/library/src/main/ets/ImageKnifeDispatcher.ets index 3ba5f03..196cabb 100644 --- a/library/src/main/ets/ImageKnifeDispatcher.ets +++ b/library/src/main/ets/ImageKnifeDispatcher.ets @@ -151,6 +151,9 @@ export class ImageKnifeDispatcher { let requestJobResult = res as RequestJobResult let pixelmap = requestJobResult === undefined ? undefined : requestJobResult.pixelMap if (pixelmap === undefined) { + if (currentRequest.imageKnifeOption.onLoadListener && currentRequest.imageKnifeOption.onLoadListener.onLoadFailed && requestJobResult.loadFail) { + currentRequest.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail); + } if (requestList !== undefined) { requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { if (requestWithSource.source === ImageKnifeRequestSource.SRC && currentRequest.imageKnifeOption.errorholderSrc !== undefined) { @@ -165,6 +168,7 @@ export class ImageKnifeDispatcher { else { LogUtil.log("error: no requestlist need to draw for key = " + memoryKey) } + return; } // 保存文件缓存 if (requestJobResult.bufferSize > 0 && currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.Memory) { @@ -202,6 +206,9 @@ export class ImageKnifeDispatcher { if (requestWithSource.source == ImageKnifeRequestSource.SRC) { requestWithSource.request.requestState = ImageKnifeRequestState.COMPLETE + if(currentRequest.imageKnifeOption.onLoadListener && currentRequest.imageKnifeOption.onLoadListener.onLoadSuccess) { + currentRequest.imageKnifeOption.onLoadListener.onLoadSuccess(ImageKnifeData.source); + } } else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) { requestWithSource.request.requestState = ImageKnifeRequestState.ERROR } @@ -251,6 +258,7 @@ export class ImageKnifeDispatcher { async function requestJob(request: RequestJobRequest): Promise { let resBuf: ArrayBuffer | undefined let bufferSize: number = 0 + let loadError: string = ''; class RequestData { receiveSize: number = 2000 @@ -322,6 +330,7 @@ async function requestJob(request: RequestJobRequest): Promise { + loadError = err.message; LogUtil.error("requestInStream ERROR : err = " + JSON.stringify(err)); }); @@ -334,14 +343,23 @@ async function requestJob(request: RequestJobRequest): Promise { + console.error("Load Failed Reason: " + err); + }, + onLoadSuccess: (data) => { + if(typeof data == 'string') { + return b = data; + } + return data; + }, + }, + } + if (ImageKnifeOption.onLoadListener && ImageKnifeOption.onLoadListener.onLoadSuccess && ImageKnifeOption.onLoadListener.onLoadFailed) { + ImageKnifeOption.onLoadListener.onLoadSuccess(a); + ImageKnifeOption.onLoadListener.onLoadFailed(a); + } + expect(a).assertEqual(b); + }); + }); +} \ No newline at end of file diff --git a/library/src/test/List.test.ets b/library/src/test/List.test.ets index bb5b5c3..11c3bc2 100644 --- a/library/src/test/List.test.ets +++ b/library/src/test/List.test.ets @@ -1,5 +1,7 @@ +import imageKnifeOptionTest from './ImageKnifeOption.test'; import localUnitTest from './LocalUnit.test'; export default function testsuite() { localUnitTest(); + imageKnifeOptionTest(); } \ No newline at end of file