react-native-refresh-loadmore-recyclerlistview
Version:
The listview that you need and deserve. It was built for performance, uses cell recycling to achieve smooth scrolling.
156 lines (143 loc) • 5.13 kB
JavaScript
/***
Use this component inside your ReactJS Application.
A scrollable list with different item type
*/
import React, {Component} from 'react';
import {RecyclerListView, DataProvider, LayoutProvider} from 'recyclerlistview';
const ViewTypes = {
FULL: 0,
HALF_LEFT: 1,
HALF_RIGHT: 2,
};
let containerCount = 0;
class CellContainer extends React.Component {
constructor(args) {
super(args);
this._containerId = containerCount++;
}
render() {
return <div {...this.props}>{this.props.children}<div>Cell Id: {this._containerId}</div></div>;
}
}
/***
* To test out just copy this component and render in you root component
*/
export default class RecycleTestComponent extends React.Component {
constructor(args) {
super(args);
let width = window.innerWidth;
//Create the data provider and provide method which takes in two rows of data and return if those two are different or not.
let dataProvider = new DataProvider((r1, r2) => {
return r1 !== r2;
});
//Create the layout provider
//First method: Given an index return the type of item e.g ListItemType1, ListItemType2 in case you have variety of items in your list/grid
//Second: Given a type and object set the height and width for that type on given object
//If you need data based check you can access your data provider here
//You'll need data in most cases, we don't provide it by default to enable things like data virtualization in the future
//NOTE: For complex lists LayoutProvider will also be complex it would then make sense to move it to a different file
this._layoutProvider = new LayoutProvider(
index => {
if (index % 3 === 0) {
return ViewTypes.FULL;
} else if (index % 3 === 1) {
return ViewTypes.HALF_LEFT;
} else {
return ViewTypes.HALF_RIGHT;
}
},
(type, dim) => {
switch (type) {
case ViewTypes.HALF_LEFT:
dim.width = width / 2 - 0.0001;
dim.height = 160;
break;
case ViewTypes.HALF_RIGHT:
dim.width = width / 2;
dim.height = 160;
break;
case ViewTypes.FULL:
dim.width = width;
dim.height = 140;
break;
default:
dim.width = 0;
dim.height = 0;
}
}
);
this._rowRenderer = this._rowRenderer.bind(this);
//Since component should always render once data has changed, make data provider part of the state
this.state = {
dataProvider: dataProvider.cloneWithRows(this._generateArray(300)),
};
}
_generateArray(n) {
let arr = new Array(n);
for (let i = 0; i < n; i++) {
arr[i] = i;
}
return arr;
}
//Given type and data return the view component
_rowRenderer(type, data) {
//You can return any view here, CellContainer has no special significance
switch (type) {
case ViewTypes.HALF_LEFT:
return (
<CellContainer style={styles.containerGridLeft}>
<div>Data: {data}</div>
</CellContainer>
);
case ViewTypes.HALF_RIGHT:
return (
<CellContainer style={styles.containerGridRight}>
<div>Data: {data}</div>
</CellContainer>
);
case ViewTypes.FULL:
return (
<CellContainer style={styles.container}>
<div>Data: {data}</div>
</CellContainer>
);
default:
return null;
}
}
render() {
return <RecyclerListView useWindowScroll={true} layoutProvider={this._layoutProvider} dataProvider={this.state.dataProvider} rowRenderer={this._rowRenderer} />;
}
}
const styles = {
container: {
justifyContent: 'space-around',
alignItems: 'center',
flex: 1,
display: 'flex',
flexDirection: 'column',
height: '100%',
width: '100%',
border: '0.5px solid black',
},
containerGridLeft: {
justifyContent: 'space-around',
alignItems: 'center',
flex: 1,
display: 'flex',
flexDirection: 'column',
height: '100%',
width: '100%',
border: '0.5px solid black',
},
containerGridRight: {
justifyContent: 'space-around',
alignItems: 'center',
flex: 1,
display: 'flex',
flexDirection: 'column',
height: '100%',
width: '100%',
border: '0.5px solid black',
},
};