├── .babelrc
├── LICENSE.md
├── README.md
├── index.js
├── package.json
└── src
├── GiftedVirtualizedList.js
└── InfiniteVirtualizedList.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "react-native"
4 | ]
5 | }
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 iwater
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Gifted ListView
2 |
3 | A new InfiniteList for react-native 0.43+ that compose react-virtualized/InfiniteLoader with the new react-native/VirtualizedList component, and a drop replacement component of react-native-gifted-listview
4 |
5 |
6 |
7 | ### Changelog
8 | #### 0.1.5
9 | - Pull-to-refresh
10 | #### 0.1.4
11 | - react-native 0.43.0+
12 | #### 0.1.0
13 | - the first version
14 |
15 |
16 |
17 | ### GiftedListView Simple example
18 |
19 | below code was take from react-native-gifted-listview
20 | just replace one line
21 |
22 | ```js
23 | var React = require('react-native');
24 | var {
25 | StyleSheet,
26 | Text,
27 | View,
28 | TouchableHighlight
29 | } = React;
30 |
31 |
32 | // var GiftedListView = require('react-native-gifted-listview');
33 | import { GiftedListView } from 'react-native-infinite-virtualized-list'
34 |
35 | var Example = React.createClass({
36 |
37 | /**
38 | * Will be called when refreshing
39 | * Should be replaced by your own logic
40 | * @param {number} page Requested page to fetch
41 | * @param {function} callback Should pass the rows
42 | * @param {object} options Inform if first load
43 | */
44 | _onFetch(page = 1, callback, options) {
45 | setTimeout(() => {
46 | var rows = ['row '+((page - 1) * 3 + 1), 'row '+((page - 1) * 3 + 2), 'row '+((page - 1) * 3 + 3)];
47 | if (page === 3) {
48 | callback(rows, {
49 | allLoaded: true, // the end of the list is reached
50 | });
51 | } else {
52 | callback(rows);
53 | }
54 | }, 1000); // simulating network fetching
55 | },
56 |
57 |
58 | /**
59 | * When a row is touched
60 | * @param {object} rowData Row data
61 | */
62 | _onPress(rowData) {
63 | console.log(rowData+' pressed');
64 | },
65 |
66 | /**
67 | * Render a row
68 | * @param {object} rowData Row data
69 | */
70 | _renderRowView(rowData) {
71 | return (
72 | this._onPress(rowData)}
76 | >
77 | {rowData}
78 |
79 | );
80 | },
81 |
82 | render() {
83 | return (
84 |
85 |
86 | index} // you need this for VirtualizedList
101 | />
102 |
103 | );
104 | }
105 | });
106 |
107 | var styles = {
108 | container: {
109 | flex: 1,
110 | backgroundColor: '#FFF',
111 | },
112 | navBar: {
113 | height: 64,
114 | backgroundColor: '#CCC'
115 | },
116 | row: {
117 | padding: 10,
118 | height: 44,
119 | },
120 | };
121 | ```
122 |
123 |
124 | ### InfiniteVirtualizedList Advanced example
125 |
126 | [See src/GiftedVirtualizedList.js](src/GiftedVirtualizedList.js)
127 |
128 |
129 | ### Installation
130 |
131 | ```npm install react-native-infinite-virtualized-list --save```
132 |
133 |
134 | ### Features
135 | - [x] Pull-to-refresh
136 | - [x] Infinite scrolling
137 | - [x] Loader for first display
138 | - [x] Default view when no content to display
139 | - [x] Customizable (see advanced example)
140 |
141 |
142 |
143 | ### License
144 |
145 | [MIT](LICENSE.md)
146 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import GiftedListView from './src/GiftedVirtualizedList'
2 | import InfiniteVirtualizedList from './src/InfiniteVirtualizedList'
3 |
4 | exports.GiftedListView = GiftedListView
5 | export default InfiniteVirtualizedList
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-infinite-virtualized-list",
3 | "version": "0.1.14",
4 | "homepage": "https://github.com/iwater/react-native-infinite-virtualized-list",
5 | "description": "A new InfiniteList that compose react-virtualized/InfiniteLoader with the react-native/VirtualizedList component, and a drop replacement component of react-native-gifted-listview",
6 | "main": "index.js",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/iwater/react-native-infinite-virtualized-list.git"
13 | },
14 | "bugs": {
15 | "url": "https://github.com/iwater/react-native-infinite-virtualized-list/issues"
16 | },
17 | "keywords": [
18 | "react",
19 | "reactjs",
20 | "react-native",
21 | "react-component",
22 | "virtual",
23 | "list",
24 | "scrolling",
25 | "infinite",
26 | "virtualized",
27 | "virtualizedlist",
28 | "listview",
29 | "infinite-scrolling",
30 | "ios",
31 | "android"
32 | ],
33 | "peerDependencies": {
34 | "react": ">=15.4.2",
35 | "react-native": ">=0.43.0",
36 | "prop-types": "^15.6.0"
37 | },
38 | "dependencies": {
39 | "react-virtualized": ">=9.2.2"
40 | },
41 | "author": "iwater ",
42 | "license": "MIT"
43 | }
44 |
--------------------------------------------------------------------------------
/src/GiftedVirtualizedList.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import InfiniteVirtualizedList from './InfiniteVirtualizedList'
4 |
5 | export default class GiftedVirtualizedList extends React.PureComponent {
6 | static propTypes = {
7 | onFetch: PropTypes.func.isRequired,
8 | rowView: PropTypes.func.isRequired,
9 | paginationWaitingView: PropTypes.func.isRequired,
10 | emptyView: PropTypes.func,
11 | paginationAllLoadedView: PropTypes.func.isRequired,
12 | refreshable: PropTypes.bool.isRequired,
13 | enableEmptySections: PropTypes.bool.isRequired,
14 | pagination: PropTypes.bool.isRequired,
15 | removeRow: PropTypes.func,
16 | }
17 |
18 | state = {
19 | list: [],
20 | page: 1,
21 | refreshing: false,
22 | }
23 |
24 | componentDidMount() {
25 | this.loadNextPage()
26 | }
27 |
28 | loadNextPage = () => {
29 | const { onFetch } = this.props
30 | this.setState({
31 | isNextPageLoading: true,
32 | })
33 | onFetch(this.state.page, (items, { allLoaded }) => {
34 | this.setState(({ list, page }) => ({
35 | isNextPageLoading: false,
36 | hasNextPage: !allLoaded,
37 | list: list.concat(Array.isArray(items) ? items : []),
38 | page: page + 1,
39 | refreshing: false,
40 | }))
41 | })
42 | }
43 |
44 | refresh = () => {
45 | this.setState({
46 | list: [],
47 | page: 1,
48 | refreshing: true,
49 | }, this.loadNextPage )
50 | }
51 |
52 | _refresh = () => {
53 | this.refresh()
54 | }
55 |
56 | removeItem = (row) => {
57 | this.setState(({list}, {removeRow = l => l}) => ({
58 | list: removeRow(list, row)
59 | }))
60 | }
61 |
62 | renderItem = ({ item, index }) => {
63 | return this.props.rowView(item, index)
64 | }
65 |
66 | render() {
67 | const { list, hasNextPage, isNextPageLoading, refreshing } = this.state
68 | const { emptyView, paginationWaitingView, headerView, refreshable, ...otherProps } = this.props
69 |
70 | if (emptyView && list.length === 0) return emptyView()
71 | return (
72 | list[index]}
80 | getItemCount={() => list.length}
81 | ListHeaderComponent={headerView}
82 | onRefresh={refreshable ? this.refresh : null}
83 | refreshing={refreshing}
84 | {...otherProps}
85 | />
86 | )
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/InfiniteVirtualizedList.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import { VirtualizedList } from 'react-native'
4 | import { InfiniteLoader } from 'react-virtualized/dist/commonjs/InfiniteLoader'
5 |
6 | const noop = () => {}
7 |
8 | export default class InfiniteVirtualizedList extends React.Component {
9 | static propTypes = {
10 | hasNextPage: PropTypes.bool.isRequired,
11 | isNextPageLoading: PropTypes.bool.isRequired,
12 | loadNextPage: PropTypes.func.isRequired,
13 | renderItem: PropTypes.func.isRequired,
14 | paginationWaitingView: PropTypes.func,
15 | data: PropTypes.arrayOf(PropTypes.shape()).isRequired,
16 | }
17 |
18 | static defaultProps = {
19 | paginationWaitingView: noop,
20 | }
21 |
22 | render() {
23 | const { hasNextPage, isNextPageLoading, data, loadNextPage, renderItem, paginationWaitingView } = this.props
24 | // If there are more items to be loaded then add an extra row to hold a loading indicator.
25 | const rowCount = hasNextPage
26 | ? data.length + 1
27 | : data.length
28 |
29 | // Only load 1 page of items at a time.
30 | // Pass an empty callback to InfiniteLoader in case it asks us to load more than once.
31 | const loadMoreRows = isNextPageLoading
32 | ? noop
33 | : loadNextPage
34 |
35 | // Every row is loaded except for our loading indicator row.
36 | const isRowLoaded = ({ index }) => !hasNextPage || index < data.length
37 |
38 | // Render a list item or a loading indicator.
39 | const rowRenderer = ({ item, index }) => {
40 | if (!isRowLoaded({ index })) {
41 | return paginationWaitingView()
42 | }
43 | return renderItem({ item, index })
44 | }
45 |
46 | return (
47 |
52 | {({ onRowsRendered, registerChild }) => (
53 | {
55 | if (viewableItems.length > 0) {
56 | onRowsRendered({
57 | startIndex: viewableItems[0].index,
58 | stopIndex: viewableItems[viewableItems.length - 1].index,
59 | })
60 | }
61 | }}
62 | ref={registerChild}
63 | renderItem={rowRenderer}
64 | {...this.props}
65 | />
66 | )}
67 |
68 | )
69 | }
70 | }
71 |
--------------------------------------------------------------------------------