import { BasicPrefetcher, IDataSourcePrefetching } from '@netteam/prefetcher';
import { image } from '@kit.ImageKit';
import { create10x10Bitmap, getRandomColor } from 'examples_common'; // Code of these functions is omitted for brevity
const ITEMS_ON_SCREEN = 8;
@Component
export struct PrefetcherDemoComponent {
private readonly dataSource = new SimulationDataSource(2000, 500);
private readonly prefetcher = new BasicPrefetcher(this.dataSource);
build() {
Column() {
List() {
LazyForEach(this.dataSource, (item: PictureItem) => {
ListItem() {
PictureItemComponent({ info: item })
.height(`${100 / ITEMS_ON_SCREEN}%`)
}
}, (item: PictureItem) => item.title)
}
.onScrollIndex((start: number, end: number) => {
this.prefetcher.visibleAreaChanged(start, end);
})
}
}
}
@Component
export default struct PictureItemComponent {
@ObjectLink info: PictureItem;
build() {
Row() {
Image(this.info.imagePixelMap)
.objectFit(ImageFit.Contain)
.width('40%')
Text(this.info.title)
.width('60%')
}
}
}
@Observed
export class PictureItem {
readonly color: number;
title: string;
imagePixelMap: image.PixelMap | undefined;
key: string;
constructor(color: number, title: string) {
this.color = color;
this.title = title;
this.key = title;
}
}
type ItemIndex = number;
type TimerId = number;
class SimulationDataSource implements IDataSourcePrefetching {
private readonly items: PictureItem[];
private readonly fetchDelayMs: number;
private readonly fetches: Map<ItemIndex, TimerId> = new Map();
constructor(numItems: number, fetchDelayMs: number) {
this.items = [];
this.fetchDelayMs = fetchDelayMs;
for (let i = 0; i < numItems; i++) {
const item = new PictureItem(getRandomColor(), `Item ${i}`);
this.items.push(item);
}
}
async prefetch(index: number): Promise<void> {
const item = this.items[index];
if (item.imagePixelMap) {
return;
}
// Simulate long running operation
return new Promise<void>(resolve => {
const timeoutId = setTimeout(async () => {
this.fetches.delete(index);
const bitmap = create10x10Bitmap(item.color);
const imageSource: image.ImageSource = image.createImageSource(bitmap);
item.imagePixelMap = await imageSource.createPixelMap();
resolve();
}, this.fetchDelayMs);
this.fetches.set(index, timeoutId);
});
}
cancel(index: number): void {
const timerId = this.fetches.get(index);
if (timerId) {
this.fetches.delete(index);
clearTimeout(timerId);
}
}
totalCount(): number {
return this.items.length;
}
getData(index: number): PictureItem {
return this.items[index];
}
registerDataChangeListener(_: DataChangeListener): void {}
unregisterDataChangeListener(_: DataChangeListener): void {}
}