RefreshControl control component of react native is used with refreshControl={} prop of ListView, This component will allow us to add Swipe Down Pull to again update JSON data functionality. RefreshControl has its own progress loading indicator which shows automatically when application use swipe down his finger on mobile phone screen and after releasing the finger it will start showing progress loading indicator and in the back start the web call again to parse JSON data into ListView. So in this tutorial we would going to implement Swipe Down Pull to Refresh ListView Using RefreshControl iOS Android React Native App Example Tutorial on JSON Parsing ListView.
Contents in this project Swipe Down Pull to Refresh ListView Using RefreshControl iOS Android React Native App Example Tutorial:
1. We are using our own custom JSON from another tutorial of ours, So if you want to know, how to make your own JSON using PHP MySQL database then read our this tutorial.
Screenshot of JSON used in current tutorial:
2. Import StyleSheet, ActivityIndicator, ListView, Text, View, Alert and RefreshControl component in your project.
1
2
3
|
import React, { Component } from ‘react’;
import { StyleSheet, ActivityIndicator, ListView, Text, View, Alert, RefreshControl } from ‘react-native’;
|
3. Create constructor() in your project and make 2 State named as isLoading and refreshing. isLoading is used to show and hide the Activity indicator while app loads first time and the refreshing state is used with RefreshControl .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
constructor(props) {
super(props);
this.state = {
isLoading: true,
refreshing: false
}
this.webCall();
}
|
4. Create a function named as GetItem(), This function would show us the current selected item of ListView in alert dialog message.
1
2
3
4
5
|
GetItem (fruit_name) {
Alert.alert(fruit_name);
}
|
5. Create a function named as webCall(), This function is our top priority function and used to parse JSON from URL and store in dataSource. We are using the fetch() method to parse JSON.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
webCall=()=>{
return fetch(‘https://reactnativecode.000webhostapp.com/FruitsList.php’)
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
isLoading: false,
dataSource: ds.cloneWithRows(responseJson),
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
}
|
6. Create a function named as ListViewItemSeparator(), This function would display a horizontal line between each ListView item.
1
2
3
4
5
6
7
8
9
10
11
|
ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: “100%”,
backgroundColor: “#000”,
}}
/>
);
}
|
7. Create another function named as onRefresh(), We would use this function to call the above webCall() function. We will call this function form RefreshControl component. Inside this function we would firstly delete all the current items of ListView and make the ListView empty and using the web call again fill the data.
1
2
3
4
5
6
7
8
9
|
onRefresh() {
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({dataSource : ds.cloneWithRows([ ])})
this.webCall();
}
|
8. Create a IF condition to show the activity indicator on first time app loading time in render’s block.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
);
}
|
9. Create ListView component in render’s return block with RefreshControl component.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.MainContainer}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
enableEmptySections = {true}
renderRow={(rowData) => <Text style={styles.rowViewContainer}
onPress={this.GetItem.bind(this, rowData.fruit_name)} >{rowData.fruit_name}</Text>}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this.onRefresh.bind(this)}
/>
}
/>
</View>
);
}
|
10. Creating Style.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
const styles = StyleSheet.create({
MainContainer :{
justifyContent: ‘center’,
flex:1,
margin: 10
},
rowViewContainer: {
fontSize: 20,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
}
});
|
11. Complete source code for App.js File :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
import React, { Component } from ‘react’;
import {StyleSheet, ActivityIndicator, ListView, Text, View, Alert, RefreshControl } from ‘react-native’;
export default class Project extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
refreshing: false
}
this.webCall();
}
GetItem (fruit_name) {
Alert.alert(fruit_name);
}
webCall=()=>{
return fetch(‘https://reactnativecode.000webhostapp.com/FruitsList.php’)
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
isLoading: false,
dataSource: ds.cloneWithRows(responseJson),
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
}
ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: “100%”,
backgroundColor: “#000”,
}}
/>
);
}
onRefresh() {
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({dataSource : ds.cloneWithRows([ ])})
this.webCall();
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.MainContainer}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
enableEmptySections = {true}
renderRow={(rowData) => <Text style={styles.rowViewContainer}
onPress={this.GetItem.bind(this, rowData.fruit_name)} >{rowData.fruit_name}</Text>}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this.onRefresh.bind(this)}
/>
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer :{
justifyContent: ‘center’,
flex:1,
margin: 10
},
rowViewContainer: {
fontSize: 20,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
}
});
|
Screenshots: