1e41f4b71Sopenharmony_ci# @ohos.arkui.Prefetcher (Prefetching) 2e41f4b71Sopenharmony_ci配合LazyForEach,为List、Grid、Waterfall和Swiper等容器组件滑动浏览时提供内容预加载能力,提升用户浏览体验。 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci> **说明:** 5e41f4b71Sopenharmony_ci> 6e41f4b71Sopenharmony_ci> 本模块首批接口从API version 12开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ci## 导入模块 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci```ts 11e41f4b71Sopenharmony_ciimport { BasicPrefetcher, IDataSourcePrefetching, IPrefetcher } from '@kit.ArkUI'; 12e41f4b71Sopenharmony_ci``` 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci## IPrefetcher 16e41f4b71Sopenharmony_ci实现此接口以提供预取能力。 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ci### setDataSource 23e41f4b71Sopenharmony_cisetDataSource(dataSource: IDataSourcePrefetching): void; 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci设置支持预取的DataSource以绑定到Prefetcher 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci**参数说明:** 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ci| 参数名 | 类型 | 必填 | 说明 | 34e41f4b71Sopenharmony_ci|------------|---------------------------------------------------|----|------------| 35e41f4b71Sopenharmony_ci| dataSource | [IDataSourcePrefetching](#idatasourceprefetching) | 是 | 支持预取能力的数据源 | 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci```typescript 38e41f4b71Sopenharmony_ciclass MyPrefetcher implements IPrefetcher { 39e41f4b71Sopenharmony_ci private dataSource?: IDataSourcePrefetching; 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci setDataSource(dataSource: IDataSourcePrefetching): void { 42e41f4b71Sopenharmony_ci this.dataSource = dataSource; 43e41f4b71Sopenharmony_ci } 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci visibleAreaChanged(minVisible: number, maxVisible: number): void { 46e41f4b71Sopenharmony_ci this.dataSource?.prefetch(minVisible); 47e41f4b71Sopenharmony_ci } 48e41f4b71Sopenharmony_ci} 49e41f4b71Sopenharmony_ci``` 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ci### visibleAreaChanged 52e41f4b71Sopenharmony_civisibleAreaChanged(minVisible: number, maxVisible: number): void 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci当可见区域边界发生改变时调用此方法。支持与`List`、`Grid`、`Waterfall`和`Swiper`组件配合使用 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci**参数说明:** 61e41f4b71Sopenharmony_ci 62e41f4b71Sopenharmony_ci| 参数名 | 类型 | 必填 | 说明 | 63e41f4b71Sopenharmony_ci|------------|--------|----|-----------| 64e41f4b71Sopenharmony_ci| minVisible | number | 是 | 列表可见区域的上界 | 65e41f4b71Sopenharmony_ci| maxVisible | number | 是 | 列表可见区域的下界 | 66e41f4b71Sopenharmony_ci 67e41f4b71Sopenharmony_ci```typescript 68e41f4b71Sopenharmony_ciclass MyPrefetcher implements IPrefetcher { 69e41f4b71Sopenharmony_ci private dataSource?: IDataSourcePrefetching; 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci setDataSource(dataSource: IDataSourcePrefetching): void { 72e41f4b71Sopenharmony_ci this.dataSource = dataSource; 73e41f4b71Sopenharmony_ci } 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci visibleAreaChanged(minVisible: number, maxVisible: number): void { 76e41f4b71Sopenharmony_ci this.dataSource?.prefetch(minVisible); 77e41f4b71Sopenharmony_ci } 78e41f4b71Sopenharmony_ci} 79e41f4b71Sopenharmony_ci``` 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci## BasicPrefetcher 82e41f4b71Sopenharmony_ciBasicPrefetcher是IPrefetcher的基础实现。它提供了一种智能数据预取算法,以根据屏幕上可见区域的实时变化和预取持续时间的变化来决定应预取哪些数据项。它还可以根据用户的滚动操作来确定哪些预取请求应该被取消。 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 85e41f4b71Sopenharmony_ci 86e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ci### constructor 89e41f4b71Sopenharmony_ciconstructor(dataSource?: IDataSourcePrefetching) 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ci传入支持预取的DataSource以绑定到Prefetcher 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci**参数说明:** 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ci| 参数名 | 类型 | 必填 | 说明 | 100e41f4b71Sopenharmony_ci|------------|---------------------------------------------------|----|------------| 101e41f4b71Sopenharmony_ci| dataSource | [IDataSourcePrefetching](#idatasourceprefetching) | 否 | 支持预取能力的数据源 | 102e41f4b71Sopenharmony_ci 103e41f4b71Sopenharmony_ci### setDataSource 104e41f4b71Sopenharmony_cisetDataSource(dataSource: IDataSourcePrefetching): void; 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci设置支持预取的DataSource以绑定到Prefetcher 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci**参数说明:** 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci| 参数名 | 类型 | 必填 | 说明 | 115e41f4b71Sopenharmony_ci|------------|---------------------------------------------------|----|------------| 116e41f4b71Sopenharmony_ci| dataSource | [IDataSourcePrefetching](#idatasourceprefetching) | 是 | 支持预取能力的数据源 | 117e41f4b71Sopenharmony_ci 118e41f4b71Sopenharmony_ci### visibleAreaChanged 119e41f4b71Sopenharmony_civisibleAreaChanged(minVisible: number, maxVisible: number): void 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ci当可见区域边界发生改变时调用此方法。支持与`List`、`Grid`、`Waterfall`和`Swiper`组件配合使用 122e41f4b71Sopenharmony_ci 123e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci**参数说明:** 128e41f4b71Sopenharmony_ci 129e41f4b71Sopenharmony_ci| 参数名 | 类型 | 必填 | 说明 | 130e41f4b71Sopenharmony_ci|------------|--------|----|-----------| 131e41f4b71Sopenharmony_ci| minVisible | number | 是 | 列表可见区域的上界 | 132e41f4b71Sopenharmony_ci| maxVisible | number | 是 | 列表可见区域的下界 | 133e41f4b71Sopenharmony_ci 134e41f4b71Sopenharmony_ci## IDataSourcePrefetching 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci实现该接口,提供具备预取能力的DataSource 137e41f4b71Sopenharmony_ci 138e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 139e41f4b71Sopenharmony_ci 140e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 141e41f4b71Sopenharmony_ci 142e41f4b71Sopenharmony_ci### prefetch 143e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 144e41f4b71Sopenharmony_ci 145e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 146e41f4b71Sopenharmony_ci 147e41f4b71Sopenharmony_ci**参数说明:** 148e41f4b71Sopenharmony_ci 149e41f4b71Sopenharmony_ci| 参数名 | 类型 | 必填 | 说明 | 150e41f4b71Sopenharmony_ci|-------|--------|----|----------| 151e41f4b71Sopenharmony_ci| index | number | 是 | 预取数据项索引值 | 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci### cancel 154e41f4b71Sopenharmony_ci**元服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 155e41f4b71Sopenharmony_ci 156e41f4b71Sopenharmony_ci**系统能力:** SystemCapability.ArkUI.ArkUI.Full 157e41f4b71Sopenharmony_ci 158e41f4b71Sopenharmony_ci**参数说明:** 159e41f4b71Sopenharmony_ci 160e41f4b71Sopenharmony_ci| 参数名 | 类型 | 必填 | 说明 | 161e41f4b71Sopenharmony_ci|-------|--------|----|------------| 162e41f4b71Sopenharmony_ci| index | number | 是 | 取消预取数据项索引值 | 163e41f4b71Sopenharmony_ci 164e41f4b71Sopenharmony_ci列表内容移出屏幕时(比如列表快速滑动场景下),预取算法判断屏幕以外的Item可以被取消预取时,该方法即会被调用。例如,如果HTTP框架支持请求取消,则可以在此处取消在prefetch中发起的网络请求。 165e41f4b71Sopenharmony_ci 166e41f4b71Sopenharmony_ci## 示例 167e41f4b71Sopenharmony_ci 168e41f4b71Sopenharmony_ci```typescript 169e41f4b71Sopenharmony_ciimport { BasicPrefetcher, IDataSourcePrefetching } from '@kit.ArkUI'; 170e41f4b71Sopenharmony_ciimport { image } from '@kit.ImageKit'; 171e41f4b71Sopenharmony_ci 172e41f4b71Sopenharmony_ciconst ITEMS_ON_SCREEN = 8; 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ci@Entry 175e41f4b71Sopenharmony_ci@Component 176e41f4b71Sopenharmony_cistruct PrefetcherDemoComponent { 177e41f4b71Sopenharmony_ci private readonly dataSource = new MyDataSource(2000, 500); 178e41f4b71Sopenharmony_ci private readonly prefetcher = new BasicPrefetcher(this.dataSource); 179e41f4b71Sopenharmony_ci 180e41f4b71Sopenharmony_ci build() { 181e41f4b71Sopenharmony_ci Column() { 182e41f4b71Sopenharmony_ci List() { 183e41f4b71Sopenharmony_ci LazyForEach(this.dataSource, (item: PictureItem) => { 184e41f4b71Sopenharmony_ci ListItem() { 185e41f4b71Sopenharmony_ci PictureItemComponent({ info: item }) 186e41f4b71Sopenharmony_ci .height(`${100 / ITEMS_ON_SCREEN}%`) 187e41f4b71Sopenharmony_ci } 188e41f4b71Sopenharmony_ci }, (item: PictureItem) => item.title) 189e41f4b71Sopenharmony_ci } 190e41f4b71Sopenharmony_ci .onScrollIndex((start: number, end: number) => { 191e41f4b71Sopenharmony_ci this.prefetcher.visibleAreaChanged(start, end); 192e41f4b71Sopenharmony_ci }) 193e41f4b71Sopenharmony_ci } 194e41f4b71Sopenharmony_ci } 195e41f4b71Sopenharmony_ci} 196e41f4b71Sopenharmony_ci 197e41f4b71Sopenharmony_ci@Component 198e41f4b71Sopenharmony_cistruct PictureItemComponent { 199e41f4b71Sopenharmony_ci @ObjectLink info: PictureItem; 200e41f4b71Sopenharmony_ci 201e41f4b71Sopenharmony_ci build() { 202e41f4b71Sopenharmony_ci Row() { 203e41f4b71Sopenharmony_ci Image(this.info.imagePixelMap) 204e41f4b71Sopenharmony_ci .objectFit(ImageFit.Contain) 205e41f4b71Sopenharmony_ci .width('40%') 206e41f4b71Sopenharmony_ci Text(this.info.title) 207e41f4b71Sopenharmony_ci .width('60%') 208e41f4b71Sopenharmony_ci } 209e41f4b71Sopenharmony_ci } 210e41f4b71Sopenharmony_ci} 211e41f4b71Sopenharmony_ci 212e41f4b71Sopenharmony_ci@Observed 213e41f4b71Sopenharmony_ciclass PictureItem { 214e41f4b71Sopenharmony_ci readonly color: number; 215e41f4b71Sopenharmony_ci title: string; 216e41f4b71Sopenharmony_ci imagePixelMap: image.PixelMap | undefined; 217e41f4b71Sopenharmony_ci key: string; 218e41f4b71Sopenharmony_ci 219e41f4b71Sopenharmony_ci constructor(color: number, title: string) { 220e41f4b71Sopenharmony_ci this.color = color; 221e41f4b71Sopenharmony_ci this.title = title; 222e41f4b71Sopenharmony_ci this.key = title; 223e41f4b71Sopenharmony_ci } 224e41f4b71Sopenharmony_ci} 225e41f4b71Sopenharmony_ci 226e41f4b71Sopenharmony_citype ItemIndex = number; 227e41f4b71Sopenharmony_citype TimerId = number; 228e41f4b71Sopenharmony_ci 229e41f4b71Sopenharmony_ciclass MyDataSource implements IDataSourcePrefetching { 230e41f4b71Sopenharmony_ci private readonly items: PictureItem[]; 231e41f4b71Sopenharmony_ci private readonly fetchDelayMs: number; 232e41f4b71Sopenharmony_ci private readonly fetches: Map<ItemIndex, TimerId> = new Map(); 233e41f4b71Sopenharmony_ci 234e41f4b71Sopenharmony_ci constructor(numItems: number, fetchDelayMs: number) { 235e41f4b71Sopenharmony_ci this.items = []; 236e41f4b71Sopenharmony_ci this.fetchDelayMs = fetchDelayMs; 237e41f4b71Sopenharmony_ci for (let i = 0; i < numItems; i++) { 238e41f4b71Sopenharmony_ci const item = new PictureItem(getRandomColor(), `Item ${i}`) 239e41f4b71Sopenharmony_ci this.items.push(item); 240e41f4b71Sopenharmony_ci } 241e41f4b71Sopenharmony_ci } 242e41f4b71Sopenharmony_ci 243e41f4b71Sopenharmony_ci async prefetch(index: number): Promise<void> { 244e41f4b71Sopenharmony_ci const item = this.items[index]; 245e41f4b71Sopenharmony_ci if (item.imagePixelMap) { 246e41f4b71Sopenharmony_ci return; 247e41f4b71Sopenharmony_ci } 248e41f4b71Sopenharmony_ci 249e41f4b71Sopenharmony_ci // 模拟高耗时操作 250e41f4b71Sopenharmony_ci return new Promise<void>(resolve => { 251e41f4b71Sopenharmony_ci const timeoutId = setTimeout(async () => { 252e41f4b71Sopenharmony_ci this.fetches.delete(index); 253e41f4b71Sopenharmony_ci const bitmap = create10x10Bitmap(item.color); 254e41f4b71Sopenharmony_ci const imageSource: image.ImageSource = image.createImageSource(bitmap); 255e41f4b71Sopenharmony_ci item.imagePixelMap = await imageSource.createPixelMap(); 256e41f4b71Sopenharmony_ci resolve(); 257e41f4b71Sopenharmony_ci }, this.fetchDelayMs); 258e41f4b71Sopenharmony_ci 259e41f4b71Sopenharmony_ci this.fetches.set(index, timeoutId) 260e41f4b71Sopenharmony_ci }); 261e41f4b71Sopenharmony_ci } 262e41f4b71Sopenharmony_ci 263e41f4b71Sopenharmony_ci cancel(index: number): void { 264e41f4b71Sopenharmony_ci const timerId = this.fetches.get(index); 265e41f4b71Sopenharmony_ci if (timerId) { 266e41f4b71Sopenharmony_ci this.fetches.delete(index); 267e41f4b71Sopenharmony_ci clearTimeout(timerId); 268e41f4b71Sopenharmony_ci } 269e41f4b71Sopenharmony_ci } 270e41f4b71Sopenharmony_ci 271e41f4b71Sopenharmony_ci totalCount(): number { 272e41f4b71Sopenharmony_ci return this.items.length; 273e41f4b71Sopenharmony_ci } 274e41f4b71Sopenharmony_ci 275e41f4b71Sopenharmony_ci getData(index: number): PictureItem { 276e41f4b71Sopenharmony_ci return this.items[index]; 277e41f4b71Sopenharmony_ci } 278e41f4b71Sopenharmony_ci 279e41f4b71Sopenharmony_ci registerDataChangeListener(_: DataChangeListener): void { 280e41f4b71Sopenharmony_ci } 281e41f4b71Sopenharmony_ci 282e41f4b71Sopenharmony_ci unregisterDataChangeListener(_: DataChangeListener): void { 283e41f4b71Sopenharmony_ci } 284e41f4b71Sopenharmony_ci} 285e41f4b71Sopenharmony_ci 286e41f4b71Sopenharmony_cifunction getRandomColor(): number { 287e41f4b71Sopenharmony_ci const maxColorCode = 256; 288e41f4b71Sopenharmony_ci const r = Math.floor(Math.random() * maxColorCode); 289e41f4b71Sopenharmony_ci const g = Math.floor(Math.random() * maxColorCode); 290e41f4b71Sopenharmony_ci const b = Math.floor(Math.random() * maxColorCode); 291e41f4b71Sopenharmony_ci 292e41f4b71Sopenharmony_ci return (r * 256 + g) * 256 + b; 293e41f4b71Sopenharmony_ci} 294e41f4b71Sopenharmony_ci 295e41f4b71Sopenharmony_cifunction create10x10Bitmap(color: number): ArrayBuffer { 296e41f4b71Sopenharmony_ci const height = 10; 297e41f4b71Sopenharmony_ci const width = 10; 298e41f4b71Sopenharmony_ci 299e41f4b71Sopenharmony_ci const fileHeaderLength = 14; 300e41f4b71Sopenharmony_ci const bitmapInfoLength = 40; 301e41f4b71Sopenharmony_ci const headerLength = fileHeaderLength + bitmapInfoLength; 302e41f4b71Sopenharmony_ci const pixelSize = (width * 3 + 2) * height; 303e41f4b71Sopenharmony_ci 304e41f4b71Sopenharmony_ci let length = pixelSize + headerLength; 305e41f4b71Sopenharmony_ci 306e41f4b71Sopenharmony_ci const buffer = new ArrayBuffer(length); 307e41f4b71Sopenharmony_ci const view16 = new Uint16Array(buffer); 308e41f4b71Sopenharmony_ci 309e41f4b71Sopenharmony_ci view16[0] = 0x4D42; 310e41f4b71Sopenharmony_ci view16[1] = length & 0xffff; 311e41f4b71Sopenharmony_ci view16[2] = length >> 16; 312e41f4b71Sopenharmony_ci view16[5] = headerLength; 313e41f4b71Sopenharmony_ci 314e41f4b71Sopenharmony_ci let offset = 7; 315e41f4b71Sopenharmony_ci view16[offset++] = bitmapInfoLength & 0xffff; 316e41f4b71Sopenharmony_ci view16[offset++] = bitmapInfoLength >> 16; 317e41f4b71Sopenharmony_ci view16[offset++] = width & 0xffff; 318e41f4b71Sopenharmony_ci view16[offset++] = width >> 16; 319e41f4b71Sopenharmony_ci view16[offset++] = height & 0xffff; 320e41f4b71Sopenharmony_ci view16[offset++] = height >> 16; 321e41f4b71Sopenharmony_ci view16[offset++] = 1; 322e41f4b71Sopenharmony_ci view16[offset++] = 24; 323e41f4b71Sopenharmony_ci 324e41f4b71Sopenharmony_ci const b = color & 0xff; 325e41f4b71Sopenharmony_ci const g = (color >> 8) & 0xff; 326e41f4b71Sopenharmony_ci const r = color >> 16; 327e41f4b71Sopenharmony_ci offset = headerLength; 328e41f4b71Sopenharmony_ci const view8 = new Uint8Array(buffer); 329e41f4b71Sopenharmony_ci for (let y = 0; y < height; y++) { 330e41f4b71Sopenharmony_ci for (let x = 0; x < width; x++) { 331e41f4b71Sopenharmony_ci view8[offset++] = b; 332e41f4b71Sopenharmony_ci view8[offset++] = g; 333e41f4b71Sopenharmony_ci view8[offset++] = r; 334e41f4b71Sopenharmony_ci } 335e41f4b71Sopenharmony_ci offset += 2; 336e41f4b71Sopenharmony_ci } 337e41f4b71Sopenharmony_ci 338e41f4b71Sopenharmony_ci return buffer; 339e41f4b71Sopenharmony_ci} 340e41f4b71Sopenharmony_ci```