Skip to content

Commit

Permalink
Move GridLayoutProvider inside RLV (#462)
Browse files Browse the repository at this point in the history
* moving grid layout provider and manager inside RLV

* moving grid layout provider and manager inside RLV

* moving grid layout provider and manager inside RLV

* Update package.json

Co-authored-by: Talha Naqvi <naqvitalha@gmail.com>
  • Loading branch information
muskeinsingh and naqvitalha authored Feb 5, 2020
1 parent f1a6a48 commit b7c23d2
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 2 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"dependencies": {
"lodash.debounce": "4.0.8",
"prop-types": "15.5.8",
"recyclerlistview-gridlayoutprovider": "1.0.1",
"ts-object-utils": "0.0.5"
},
"peerDependencies": {
Expand Down
57 changes: 57 additions & 0 deletions src/core/dependencies/GridLayoutProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
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");
}
}
}
77 changes: 77 additions & 0 deletions src/core/layoutmanager/GridLayoutManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { LayoutProvider } from "./../dependencies/LayoutProvider";
import { WrapGridLayoutManager, Layout } from "./LayoutManager";
import { Dimension } from "../dependencies/LayoutProvider";

export class GridLayoutManager extends WrapGridLayoutManager {
private _maxSpan: number;
private _getSpan: (index: number) => number;
private _isGridHorizontal: boolean | undefined;
private _renderWindowSize: Dimension;
private _acceptableRelayoutDelta: number;
constructor(
layoutProvider: LayoutProvider,
renderWindowSize: Dimension,
getSpan: (index: number) => number,
maxSpan: number,
acceptableRelayoutDelta: number,
isHorizontal?: boolean,
cachedLayouts?: Layout[],
) {
super(layoutProvider, renderWindowSize, isHorizontal, cachedLayouts);
this._getSpan = getSpan;
this._isGridHorizontal = isHorizontal;
this._renderWindowSize = renderWindowSize;
if (acceptableRelayoutDelta < 0) {
throw new Error("acceptableRelayoutDelta cannot be less than 0");
} else {
this._acceptableRelayoutDelta = acceptableRelayoutDelta;
}
if (maxSpan <= 0) {
throw new Error("Max Column Span cannot be less than or equal to 0");
} else {
this._maxSpan = maxSpan;
}
}

public overrideLayout(index: number, dim: Dimension): boolean {
// we are doing this because - when we provide decimal dimensions for a
// certain cell - the onlayout returns a different dimension in certain high end devices.
// This causes the layouting to behave weirdly as the new dimension might not adhere to the spans and the cells arrange themselves differently
// So, whenever we have layouts for a certain index, we explicitly override the dimension to those very layout values
// and call super so as to set the overridden flag as true
const layout = this.getLayouts()[index];
const heightDiff = Math.abs(dim.height - layout.height);
const widthDiff = Math.abs(dim.width - layout.width);
if (layout) {
if (this._isGridHorizontal) {
if (heightDiff < this._acceptableRelayoutDelta) {
if (widthDiff === 0) {
return false;
}
dim.height = layout.height;
}
} else {
if (widthDiff < this._acceptableRelayoutDelta) {
if (heightDiff === 0) {
return false;
}
dim.width = layout.width;
}
}
}
return super.overrideLayout(index, dim);
}

public getStyleOverridesForIndex(index: number): object | undefined {
const columnSpanForIndex = this._getSpan(index);
return this._isGridHorizontal
? {
height:
(this._renderWindowSize.height / this._maxSpan) * columnSpanForIndex,
}
: {
width:
(this._renderWindowSize.width / this._maxSpan) * columnSpanForIndex,
};
}
}
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import ContextProvider from "./core/dependencies/ContextProvider";
import DataProvider, { BaseDataProvider } from "./core/dependencies/DataProvider";
import { BaseLayoutProvider, Dimension, LayoutProvider } from "./core/dependencies/LayoutProvider";
import { GridLayoutProvider, GridLayoutManager } from "recyclerlistview-gridlayoutprovider";
import { GridLayoutProvider } from "./core/dependencies/GridLayoutProvider";
import RecyclerListView, { OnRecreateParams } from "./core/RecyclerListView";
import BaseScrollView from "./core/scrollcomponent/BaseScrollView";
import { BaseItemAnimator } from "./core/ItemAnimator";
import { AutoScroll } from "./utils/AutoScroll";
import { Layout, LayoutManager, Point, WrapGridLayoutManager } from "./core/layoutmanager/LayoutManager";
import { GridLayoutManager } from "./core/layoutmanager/GridLayoutManager";
import ProgressiveListView from "./core/ProgressiveListView";
import { DebugHandlers } from "./core/devutils/debughandlers/DebugHandlers";
import { ComponentCompat } from "./utils/ComponentCompat";
Expand Down

0 comments on commit b7c23d2

Please sign in to comment.