├── LICENSE
├── README.md
├── infinite-gif.gif
├── package.json
└── src
└── index.js
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Prateek Surana
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.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-infinite-looping-scroll
2 |
3 | A react native component that lets you scroll infinitely in both directions by repeating the same items.
4 |
5 |
6 |
7 |
8 |
9 | ## Installation
10 |
11 | Run `npm install react-native-infinite-looping-scroll` in your project directory.
12 |
13 | ## Usage
14 |
15 | This snippet would produce the output shown in the above gif
16 |
17 | ```
18 | import React, { Component } from 'react';
19 | import { Platform, StyleSheet, Text, View, FlatList, } from 'react-native';
20 | import InfiniteScroll from 'react-native-infinite-looping-scroll';
21 |
22 |
23 | export default class App extends Component {
24 | constructor(props) {
25 | super(props)
26 | }
27 |
28 | render() {
29 | return (
30 |
31 | {item.key}}
34 | />
35 |
36 |
37 | );
38 | }
39 | }
40 |
41 | const styles = StyleSheet.create({
42 | container: {
43 | flex: 1,
44 | justifyContent: 'center',
45 | alignItems: 'center',
46 | backgroundColor: '#F5FCFF',
47 | },
48 | listItem: {
49 | flexDirection: 'row',
50 | justifyContent: 'space-between',
51 | alignItems: 'center',
52 | padding: 50,
53 | margin: 2,
54 | borderColor: '#0099A8',
55 | borderWidth: 10,
56 | backgroundColor: '#FEFEFE'
57 | },
58 | text: {
59 | color: '#0099A8',
60 | fontSize: 32,
61 | fontWeight: 'bold'
62 | },
63 | welcome: {
64 | fontSize: 20,
65 | textAlign: 'center',
66 | margin: 10,
67 | },
68 | instructions: {
69 | textAlign: 'center',
70 | color: '#333333',
71 | marginBottom: 5,
72 | },
73 | });
74 |
75 | ```
76 |
77 | ## Props
78 |
79 | It accepts all the [FlatList](https://facebook.github.io/react-native/docs/flatlist.html) props out of which renderItem and data are the compulsory ones and has one more extra prop called `offset` which lets you set the offset at which new data should be added. The default value is 20 and you can change it according to your item.
80 |
81 | ## Pending Tasks
82 |
83 | - [ ] Make upward and downward scroll more smooth.
84 | - [ ] The scroll view should work even when the content size is less than the layout measurement.
85 |
86 | ## Contributing
87 |
88 | This is project is still in beta at the moment, but is still very basic, so if you want to work on the above mention tasks, or you find a bug just open a PR or an issue and ping me!
89 |
--------------------------------------------------------------------------------
/infinite-gif.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prateek3255/react-native-infinite-looping-scroll/af1fdcceecbc6430a02e9288838104b8d7091870/infinite-gif.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-infinite-looping-scroll",
3 | "version": "0.0.3",
4 | "description": "A react native component that lets you scroll infinitely in both directions by repeating the same items.",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "react-native",
11 | "infinite",
12 | "scroll",
13 | "looping"
14 | ],
15 | "bugs": {
16 | "url": "https://github.com/prateek3255/react-native-infinite-looping-scroll/issues"
17 | },
18 | "dependencies": {
19 | "prop-types": "15.5.10"
20 | },
21 | "peerDependencies": {
22 | "react": "^16.0.0-beta.5",
23 | "react-native": "^0.49.1"
24 | },
25 | "devDependencies": {
26 | "babel-jest": "22.4.4",
27 | "babel-preset-react-native": "4.0.0",
28 | "jest": "22.4.4",
29 | "react-test-renderer": "16.3.1"
30 | },
31 | "repository": {
32 | "type": "git",
33 | "url": "git+https://github.com/prateek3255/react-native-infinite-looping-scroll.git"
34 | },
35 | "author": "Prateek Surana ",
36 | "license": "MIT"
37 | }
38 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { FlatList } from 'react-native';
3 | import PropTypes from 'prop-types'
4 |
5 | export default class InfiniteScroll extends Component {
6 | constructor(props) {
7 | super(props)
8 | this.state = {
9 | data: this.props.data,
10 | end: true,
11 | }
12 | length = this.state.data.length
13 | data = this.state.data.slice()
14 | }
15 | checkScroll({ layoutMeasurement, contentOffset, contentSize }) {
16 | if (this.state.data.length >= length * 3)
17 | this.setState(prevState => ({
18 | data: prevState.data.slice(length * 2)
19 | }))
20 |
21 | if (contentOffset.y <= this.props.offset) {
22 | this.setState(prevState => ({
23 | data: [...prevState.data, ...data],
24 | }), () => this.infListRef.scrollToIndex({ index: length, animated: false }))
25 | }
26 | if (layoutMeasurement.height + contentOffset.y >= contentSize.height - this.props.offset && this.state.end) {
27 | this.setState(prevState => ({
28 | data: [...prevState.data, ...data],
29 | end: false
30 | }))
31 | }
32 | else {
33 | this.setState({
34 | end: true
35 | })
36 | }
37 |
38 | }
39 | componentDidMount() {
40 | this.setState(prevState => ({
41 | data: [...prevState.data, ...prevState.data]
42 | }))
43 | setTimeout(() => { this.infListRef.scrollToIndex({ animated: false, index: length }) }, 500);
44 |
45 | }
46 | render() {
47 | return (
48 |
49 | { this.infListRef = ref; }}
52 | data={this.state.data}
53 | renderItem={this.props.renderItem}
54 | onScroll={({ nativeEvent }) => this.checkScroll(nativeEvent)}
55 | showsVerticalScrollIndicator={this.props.showsVerticalScrollIndicator}
56 | />
57 | );
58 | }
59 | }
60 |
61 | InfiniteScroll.propTypes = {
62 | offset: PropTypes.number,
63 | showsVerticalScrollIndicator: PropTypes.bool
64 | }
65 |
66 | InfiniteScroll.defaultProps = {
67 | offset: 20,
68 | showsVerticalScrollIndicator: false
69 | };
--------------------------------------------------------------------------------