recyclerlistview
Version:
The listview that you need and deserve. It was built for performance, uses cell recycling to achieve smooth scrolling.
58 lines (53 loc) • 2.39 kB
text/typescript
import { LayoutProvider, Dimension } from "./LayoutProvider";
import { Layout, LayoutManager } from "../layoutmanager/LayoutManager";
import { GridLayoutManager } from "../layoutmanager/GridLayoutManager";
export class GridLayoutProvider extends LayoutProvider {
private _getHeightOrWidth: (index: number) => number;
private _getSpan: (index: number) => number;
private _maxSpan: number;
private _renderWindowSize?: Dimension;
private _isHorizontal?: boolean;
private _acceptableRelayoutDelta: number;
constructor(
maxSpan: number,
getLayoutType: (index: number) => string | number,
getSpan: (index: number) => number,
// If horizonal return width while spans will be rowspans. Opposite holds true if not horizontal
getHeightOrWidth: (index: number) => number,
acceptableRelayoutDelta?: number,
) {
super(
getLayoutType,
(type: string | number, dimension: Dimension, index: number) => {
this.setLayout(dimension, index);
},
);
this._getHeightOrWidth = getHeightOrWidth;
this._getSpan = getSpan;
this._maxSpan = maxSpan;
this._acceptableRelayoutDelta = ((acceptableRelayoutDelta === undefined) || (acceptableRelayoutDelta === null)) ? 1 : acceptableRelayoutDelta;
}
public newLayoutManager(renderWindowSize: Dimension, isHorizontal?: boolean, cachedLayouts?: Layout[]): LayoutManager {
this._isHorizontal = isHorizontal;
this._renderWindowSize = renderWindowSize;
return new GridLayoutManager(this, renderWindowSize, this._getSpan, this._maxSpan, this._acceptableRelayoutDelta, this._isHorizontal, cachedLayouts);
}
private setLayout(dimension: Dimension, index: number): void {
const maxSpan: number = this._maxSpan;
const itemSpan: number = this._getSpan(index);
if (itemSpan > maxSpan) {
throw new Error("Item span for index " + index + " is more than the max span");
}
if (this._renderWindowSize) {
if (this._isHorizontal) {
dimension.width = this._getHeightOrWidth(index);
dimension.height = (this._renderWindowSize.height / maxSpan) * itemSpan;
} else {
dimension.height = this._getHeightOrWidth(index);
dimension.width = (this._renderWindowSize.width / maxSpan) * itemSpan;
}
} else {
throw new Error("setLayout called before layoutmanager was created, cannot be handled");
}
}
}