Skip to content

Commit 7b5d572

Browse files
committed
Breaking changes: improved the stability of customRefreshView, fixed several bugs on Android
1 parent c284e7b commit 7b5d572

File tree

10 files changed

+106
-117
lines changed

10 files changed

+106
-117
lines changed

Example/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ android {
9696
defaultConfig {
9797
applicationId "com.example"
9898
minSdkVersion 16
99-
targetSdkVersion 22
99+
targetSdkVersion 23
100100
versionCode 1
101101
versionName "1.0"
102102
ndk {

Example/app/index.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React, {Component} from "react";
2-
import {Alert, Dimensions, View} from "react-native";
2+
import {Alert, Dimensions, View, Platform} from "react-native";
33
import {Button, Header, Icon, Input, Item, Left, Right, Text} from "native-base";
44
import styles from "./styles";
55
import LoadingSpinner from "./loadingSpinner";
66
import ControlTab from "./controlTab";
77
import FlatListItem from "./itemContainer/flatListItem";
88
import FlatListGrid from "./itemContainer/flatListGrid";
9-
import UltimateListView from "react-native-ultimate-listview";
10-
//import UltimateListView from "../src/ultimateListView";
9+
//import UltimateListView from "react-native-ultimate-listview";
10+
import UltimateListView from "../src/ultimateListView";
1111

1212

1313
const {width, height} = Dimensions.get('window');
@@ -134,13 +134,14 @@ export default class Example extends Component {
134134
ref={(ref) => this.listView = ref}
135135
key={this.state.layout} //this is important to distinguish different FlatList, default is numColumns
136136
onFetch={this.onFetch}
137-
keyExtractor={(item, index) => `${this.state.layout} - ${item}`} //this is required when you are using FlatList
137+
keyExtractor={(item, index) => `${index} - ${item}`} //this is required when you are using FlatList
138138
refreshableMode="advanced" //basic or advanced
139139

140140
item={this.renderItem} //this takes three params (item, index, separator)
141141
numColumns={this.state.layout === 'list' ? 1 : 3} //to use grid layout, simply set gridColumn > 1
142142

143143
//----Extra Config----
144+
displayDate
144145
header={this.renderHeader}
145146
paginationFetchingView={this.renderPaginationFetchingView}
146147
//sectionHeaderView={this.renderSectionHeaderView} //not supported on FlatList
@@ -149,6 +150,12 @@ export default class Example extends Component {
149150
//paginationWaitingView={this.renderPaginationWaitingView}
150151
//emptyView={this.renderEmptyView}
151152
//separator={this.renderSeparatorView}
153+
154+
//new props on v3.2.0
155+
arrowImageStyle={{width: 20, height: 20, resizeMode: 'contain'}}
156+
dateStyle={{color: 'lightgray'}}
157+
refreshViewStyle={Platform.OS === 'ios' ? {height: 80, top: -80} : {height: 80}}
158+
refreshViewHeight={80}
152159
/>
153160
</View>
154161
);

Example/app/itemContainer/flatListGrid.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default class Example extends PureComponent {
1515
const rowData = this.props.item;
1616
return (
1717
<TouchableOpacity onPress={() => this.props.onPress('GridView', rowID, rowData)}>
18-
<View style={{margin: 0.5, width: width / 3}}>
18+
<View style={{margin: 0.5, width: width / 3, paddingBottom: 15}}>
1919
<Thumbnail square source={logo} style={styles.gridThumb}/>
2020
<Text style={styles.gridText}>ID: {rowID}</Text>
2121
<Text style={styles.gridText}>{rowData}</Text>

Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
33
LastUpgradeVersion = "0830"
4-
version = "1.3">
4+
version = "1.8">
55
<BuildAction
66
parallelizeBuildables = "NO"
77
buildImplicitDependencies = "YES">
@@ -84,7 +84,6 @@
8484
buildConfiguration = "Debug"
8585
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
8686
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
87-
language = ""
8887
launchStyle = "0"
8988
useCustomWorkingDirectory = "NO"
9089
ignoresPersistentStateOnLaunch = "NO"
@@ -101,6 +100,13 @@
101100
ReferencedContainer = "container:Example.xcodeproj">
102101
</BuildableReference>
103102
</BuildableProductRunnable>
103+
<EnvironmentVariables>
104+
<EnvironmentVariable
105+
key = "OS_ACTIVITY_MODE"
106+
value = "disable"
107+
isEnabled = "YES">
108+
</EnvironmentVariable>
109+
</EnvironmentVariables>
104110
<AdditionalOptions>
105111
</AdditionalOptions>
106112
</LaunchAction>

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,20 @@ I have found some articles to explain why you need to use FlatList, instead of t
5555

5656
# Breaking Changes
5757

58-
- [ChangeLog](https://github.com/gameboyVito/react-native-ultimate-listview/wiki/ChangeLog)
5958
- See the **Release Note**
6059

6160

61+
62+
6263
# Contribution
6364

6465
@gameboyVito - gameboyvito@gmail.com
6566

66-
67+
1. Fork this Repository
68+
2. After modifying the code, commit and push to the forked repository
69+
3. Open your Github, create a pull request to me. I will review it ASAP, thanks a lot.
70+
71+
6772

6873
# License
6974

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-ultimate-listview",
3-
"version": "3.1.7",
3+
"version": "3.2.0",
44
"description": "A high performance FlatList providing customised pull-to-refresh | auto-pagination & infinite-scrolling | gridview layout | swipeable-row. The truly ultimate version that I have done the most tricky part for you, just simply follow the instructions shown below to put it in your app.",
55
"main": "index.js",
66
"scripts": {
@@ -22,8 +22,7 @@
2222
"react-component",
2323
"react-native-component",
2424
"android",
25-
"ios",
26-
"windows"
25+
"ios"
2726
],
2827
"author": {
2928
"name": "Chen Jiajie",

src/downArrow.png

1.17 KB
Loading

src/refreshableScrollView.android.js

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ const PaginationStatus = {
2525
waiting: 1,
2626
allLoaded: 2
2727
};
28-
const headerHeight = 80;
2928

3029
export default class RefreshableScrollView extends ScrollView {
3130
_offsetY = 0;
@@ -36,19 +35,14 @@ export default class RefreshableScrollView extends ScrollView {
3635
super(props);
3736
this.state = {
3837
arrowAngle: new Animated.Value(0),
39-
refreshStatus: RefreshStatus.pullToRefresh,
40-
refreshTitle: this.props.refreshableTitlePull,
41-
date: this.props.date
38+
refreshStatus: RefreshStatus.refreshing,
39+
refreshTitle: this.props.refreshableTitleRefreshing,
40+
date: this.props.date,
41+
showRefreshHeader: false
4242
};
4343
}
4444

45-
endRefresh() {
46-
this.onRefreshEnd();
47-
}
48-
4945
componentDidMount() {
50-
const height = this.props.customRefreshView ? this.props.customRefreshViewHeight : headerHeight;
51-
setTimeout(() => this.refs.scrollView.scrollTo({x: 0, y: height, animated: true}), 1);
5246
AsyncStorage.getItem(DATE_KEY, (error, result) => {
5347
if (result) {
5448
result = parseInt(result);
@@ -66,14 +60,14 @@ export default class RefreshableScrollView extends ScrollView {
6660
onScroll = (event) => {
6761
//console.log('onScroll()');
6862
const y = event.nativeEvent.contentOffset.y;
69-
const height = this.props.customRefreshView ? this.props.customRefreshViewHeight : headerHeight;
63+
const height = this.props.refreshViewHeight;
7064
if (y <= height) {
7165
this._offsetY = y - height;
7266
}
7367
if (this._dragFlag) {
7468
if (!this._isRefreshing) {
7569
if (y <= 10) {
76-
if (this.state.refresStatus !== RefreshStatus.releaseToRefresh) {
70+
if (this.state.refreshStatus !== RefreshStatus.releaseToRefresh) {
7771
this.setState({
7872
refreshStatus: RefreshStatus.releaseToRefresh,
7973
refreshTitle: this.props.refreshableTitleRelease
@@ -85,7 +79,7 @@ export default class RefreshableScrollView extends ScrollView {
8579
}).start();
8680
}
8781
} else {
88-
if (this.state.refresStatus !== RefreshStatus.pullToRefresh) {
82+
if (this.state.refreshStatus !== RefreshStatus.pullToRefresh) {
8983
this.setState({
9084
refreshStatus: RefreshStatus.pullToRefresh,
9185
refreshTitle: this.props.refreshableTitlePull
@@ -112,7 +106,7 @@ export default class RefreshableScrollView extends ScrollView {
112106
onScrollBeginDrag = (event) => {
113107
//console.log('onScrollBeginDrag()');
114108
this._dragFlag = true;
115-
const height = this.props.customRefreshView ? this.props.customRefreshViewHeight : headerHeight;
109+
const height = this.props.refreshViewHeight;
116110
this._offsetY = event.nativeEvent.contentOffset.y - height;
117111
if (this.props.onScrollBeginDrag) {
118112
this.props.onScrollBeginDrag(event)
@@ -122,7 +116,7 @@ export default class RefreshableScrollView extends ScrollView {
122116
onScrollEndDrag = (event) => {
123117
this._dragFlag = false;
124118
const y = event.nativeEvent.contentOffset.y;
125-
const height = this.props.customRefreshView ? this.props.customRefreshViewHeight : headerHeight;
119+
const height = this.props.refreshViewHeight;
126120
this._offsetY = y - height;
127121
//console.log('onScrollEndDrag()' + y);
128122
if (!this._isRefreshing) {
@@ -163,52 +157,61 @@ export default class RefreshableScrollView extends ScrollView {
163157
this._isRefreshing = false;
164158
const now = new Date().getTime();
165159
this.setState({
166-
refreshStatus: RefreshStatus.pullToRefresh,
167-
refreshTitle: this.props.refreshableTitlePull,
168-
date: dateFormat(now, this.props.dateFormat)
160+
showRefreshHeader: true,
169161
});
162+
setTimeout(() => {
163+
this.refs.scrollView.scrollTo({x: 0, y: this.props.refreshViewHeight, animated: true});
164+
this.setState({
165+
refreshStatus: RefreshStatus.pullToRefresh,
166+
refreshTitle: this.props.refreshableTitlePull,
167+
date: dateFormat(now, this.props.dateFormat)
168+
});
169+
}, 1000);
170+
170171
AsyncStorage.setItem(DATE_KEY, now.toString());
171172
Animated.timing(this.state.arrowAngle, {
172173
toValue: 0,
173174
duration: 50,
174175
easing: Easing.inOut(Easing.quad)
175176
}).start();
176-
const height = this.props.customRefreshView ? this.props.customRefreshViewHeight : headerHeight;
177-
this.refs.scrollView.scrollTo({x: 0, y: height, animated: true});
178177
}
179178
};
180179

181180
renderRefreshHeader() {
182181
if (this.props.customRefreshView) {
183182
return (
184-
this.props.customRefreshView(this.state.refresStatus, this._offsetY)
183+
<View style={[defaultHeaderStyles.header, this.props.refreshViewStyle]}>
184+
{this.props.customRefreshView(this.state.refreshStatus, this._offsetY)}
185+
</View>
185186
);
186187
}
187188

188189
return (
189-
<View style={defaultHeaderStyles.background}>
190+
<View style={[defaultHeaderStyles.header, this.props.refreshViewStyle, {height: this.state.showRefreshHeader ? this.props.refreshViewHeight : 0}]}>
190191
<View style={defaultHeaderStyles.status}>
191192
{this.renderSpinner()}
192193
<Text style={defaultHeaderStyles.statusTitle}>{this.state.refreshTitle}</Text>
193194
</View>
194195
{this.props.displayDate &&
195-
<Text style={defaultHeaderStyles.date}>{this.props.dateTitle + this.state.date}</Text>
196+
<Text
197+
style={[defaultHeaderStyles.date, this.props.dateStyle]}>{this.props.dateTitle + this.state.date}</Text>
196198
}
197199
</View>
198200
);
199201
}
200202

201203
renderSpinner() {
202-
if (this.state.refreshStatus == RefreshStatus.refreshing) {
204+
if (this.state.refreshStatus === RefreshStatus.refreshing) {
203205
return (
204206
<ActivityIndicator style={{marginRight: 10}}/>
205207
)
206208
}
207209
return (
208210
<Animated.Image
209-
source={{uri: this.props.arrowImage}}
211+
source={this.props.arrowImageSource}
210212
resizeMode={'contain'}
211213
style={[defaultHeaderStyles.arrow,
214+
this.props.arrowImageStyle,
212215
{
213216
transform: [{
214217
rotateX: this.state.arrowAngle.interpolate({
@@ -228,6 +231,7 @@ export default class RefreshableScrollView extends ScrollView {
228231
{...this.props}
229232
scrollEventThrottle={16}
230233
onScroll={this.onScroll}
234+
//contentContainerStyle={{paddingBottom: 80}}
231235
//onMomentumScrollEnd={this.onScrollEndDrag}
232236
onScrollEndDrag={this.onScrollEndDrag}
233237
onScrollBeginDrag={this.onScrollBeginDrag}>
@@ -239,14 +243,13 @@ export default class RefreshableScrollView extends ScrollView {
239243
}
240244

241245
const defaultHeaderStyles = StyleSheet.create({
242-
background: {
246+
header: {
243247
width: width,
248+
height: 80,
244249
alignItems: 'center',
245-
height: headerHeight,
246-
justifyContent: 'center',
250+
justifyContent: 'center'
247251
},
248252
status: {
249-
height: 27,
250253
flexDirection: 'row',
251254
alignItems: 'center'
252255
},

0 commit comments

Comments
 (0)