diff --git a/package.json b/package.json index 442f93f2..4a12ade5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "recyclerlistview", - "version": "3.0.5", + "version": "3.1.0-beta.2", "description": "The listview that you need and deserve. It was built for performance, uses cell recycling to achieve smooth scrolling.", "main": "dist/reactnative/index.js", "types": "dist/reactnative/index.d.ts", diff --git a/src/core/RecyclerListView.tsx b/src/core/RecyclerListView.tsx index 82c48f29..1448e602 100644 --- a/src/core/RecyclerListView.tsx +++ b/src/core/RecyclerListView.tsx @@ -105,6 +105,7 @@ export interface RecyclerListViewProps { style?: object | number; debugHandlers?: DebugHandlers; renderContentContainer?: (props?: object, children?: React.ReactNode) => React.ReactNode | null; + renderItemContainer?: (props: object, parentProps: object, children?: React.ReactNode) => React.ReactNode; //For all props that need to be proxied to inner/external scrollview. Put them in an object and they'll be spread //and passed down. For better typescript support. scrollViewProps?: object; @@ -628,6 +629,7 @@ export default class RecyclerListView

(this.props.itemAnimator, this._defaultItemAnimator)} extendedState={this.props.extendedState} internalSnapshot={this.state.internalSnapshot} + renderItemContainer={this.props.renderItemContainer} onItemLayout={this.props.onItemLayout}/> ); } @@ -796,12 +798,15 @@ RecyclerListView.propTypes = { //animations are JS driven to avoid workflow interference. Also, please note LayoutAnimation is buggy on Android. itemAnimator: PropTypes.instanceOf(BaseItemAnimator), - //The Recyclerlistview item cells are enclosed inside this item container. The idea is pass a native UI component which implements a + //All of the Recyclerlistview item cells are enclosed inside this item container. The idea is pass a native UI component which implements a //view shifting algorithm to remove the overlaps between the neighbouring views. This is achieved by shifting them by the appropriate //amount in the correct direction if the estimated sizes of the item cells are not accurate. If this props is passed, it will be used to //enclose the list items and otherwise a default react native View will be used for the same. renderContentContainer: PropTypes.func, + //This container is for wrapping individual cells that are being rendered by recyclerlistview unlike contentContainer which wraps all of them. + renderItemContainer: PropTypes.func, + //Enables you to utilize layout animations better by unmounting removed items. Please note, this might increase unmounts //on large data changes. optimizeForInsertDeleteAnimations: PropTypes.bool, diff --git a/src/core/scrollcomponent/BaseScrollComponent.tsx b/src/core/scrollcomponent/BaseScrollComponent.tsx index dda00e62..20dc54a8 100644 --- a/src/core/scrollcomponent/BaseScrollComponent.tsx +++ b/src/core/scrollcomponent/BaseScrollComponent.tsx @@ -16,6 +16,7 @@ export interface ScrollComponentProps { onLayout?: any; renderContentContainer?: (props?: object, children?: React.ReactNode) => React.ReactNode | null; renderAheadOffset: number; + layoutSize?: Dimension; } export default abstract class BaseScrollComponent extends React.Component { public abstract scrollTo(x: number, y: number, animate: boolean): void; diff --git a/src/core/viewrenderer/BaseViewRenderer.tsx b/src/core/viewrenderer/BaseViewRenderer.tsx index ff497a3e..7bf95962 100644 --- a/src/core/viewrenderer/BaseViewRenderer.tsx +++ b/src/core/viewrenderer/BaseViewRenderer.tsx @@ -28,6 +28,7 @@ export interface ViewRendererProps { internalSnapshot?: object; layoutProvider?: BaseLayoutProvider; onItemLayout?: (index: number) => void; + renderItemContainer?: (props: object, parentProps: ViewRendererProps, children?: React.ReactNode) => React.ReactNode; } export default abstract class BaseViewRenderer extends ComponentCompat, {}> { protected animatorStyleOverrides: object | undefined; diff --git a/src/platform/reactnative/scrollcomponent/ScrollComponent.tsx b/src/platform/reactnative/scrollcomponent/ScrollComponent.tsx index 46f4e97e..e1f6711b 100644 --- a/src/platform/reactnative/scrollcomponent/ScrollComponent.tsx +++ b/src/platform/reactnative/scrollcomponent/ScrollComponent.tsx @@ -31,8 +31,8 @@ export default class ScrollComponent extends BaseScrollComponent { constructor(args: ScrollComponentProps) { super(args); - this._height = 0; - this._width = 0; + this._height = (args.layoutSize && args.layoutSize.height) || 0; + this._width = (args.layoutSize && args.layoutSize.width) || 0; this._offset = 0; this._isSizeChangedCalledOnce = false; } @@ -53,6 +53,7 @@ export default class ScrollComponent extends BaseScrollComponent { }, horizontal : this.props.isHorizontal, scrollOffset : this._offset, + renderAheadOffset: this.props.renderAheadOffset, windowSize: (this.props.isHorizontal ? this._width : this._height) + this.props.renderAheadOffset, }; //TODO:Talha diff --git a/src/platform/reactnative/viewrenderer/ViewRenderer.tsx b/src/platform/reactnative/viewrenderer/ViewRenderer.tsx index 97ae2e41..d687c949 100644 --- a/src/platform/reactnative/viewrenderer/ViewRenderer.tsx +++ b/src/platform/reactnative/viewrenderer/ViewRenderer.tsx @@ -13,39 +13,42 @@ export default class ViewRenderer extends BaseViewRenderer { private _dim: Dimension = { width: 0, height: 0 }; private _viewRef: React.Component | null = null; public renderCompat(): JSX.Element { - return this.props.forceNonDeterministicRendering ? ( - - {this.renderChild()} - - ) : ( - - {this.renderChild()} - - ); + const props = this.props.forceNonDeterministicRendering + ? { + ref: this._setRef, + onLayout: this._onLayout, + style: { + flexDirection: this.props.isHorizontal ? "column" : "row", + left: this.props.x, + position: "absolute", + top: this.props.y, + ...this.props.styleOverrides, + ...this.animatorStyleOverrides, + }, + } + : { + ref: this._setRef, + style: { + left: this.props.x, + position: "absolute", + top: this.props.y, + height: this.props.height, + width: this.props.width, + ...this.props.styleOverrides, + ...this.animatorStyleOverrides, + }, + }; + return this._renderItemContainer(props, this.props, this.renderChild()) as JSX.Element; } protected getRef(): object | null { return this._viewRef; } + private _renderItemContainer(props: object, parentProps: ViewRendererProps, children: React.ReactNode): React.ReactNode { + return (this.props.renderItemContainer && this.props.renderItemContainer(props, parentProps, children)) || ({children}); + } + private _setRef = (view: React.Component | null): void => { this._viewRef = view; }