Skip to content

Commit 0ddb93a

Browse files
committed
Merge branch 'ticketea-android-support'
2 parents 82ac39a + 34348b5 commit 0ddb93a

File tree

4 files changed

+84
-36
lines changed

4 files changed

+84
-36
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ var ArticlesScreen = React.createClass({
9191
How often `ListView` produces scroll events, in ms. Defaults to a fairly low
9292
value, try setting it higher if you encounter performance issues. Keep in mind
9393
that a higher value will make the pulldown-to-refresh behaviour less responsive.
94+
- `colors: array of strings`
95+
Colors to be used for pull to refresh indicator in Android
96+
- `progressBackgroundColor: string`
97+
Color to be used for pull to refresh indicator background in Android
98+
9499

95100
### ControlledRefreshableListView
96101
Low level component used by `RefreshableListView`. Use this directly if you want

lib/ControlledRefreshableListView.js

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ var {
44
StyleSheet,
55
View,
66
Platform,
7+
PullToRefreshViewAndroid,
78
} = React
89
var ListView = require('./ListView')
910
var createElementFrom = require('./createElementFrom')
1011
var RefreshingIndicator = require('./RefreshingIndicator')
12+
var scrollToCompat = require('./scrollToCompat')
1113

1214
const SCROLL_EVENT_THROTTLE = 32
1315
const MIN_PULLDOWN_DISTANCE = 40
@@ -27,6 +29,8 @@ const LISTVIEW_REF = 'listview'
2729

2830
var ControlledRefreshableListView = React.createClass({
2931
propTypes: {
32+
colors: PropTypes.array,
33+
progressBackgroundColor: PropTypes.string,
3034
onRefresh: PropTypes.func.isRequired,
3135
isRefreshing: PropTypes.bool.isRequired,
3236
waitingForRelease: PropTypes.bool,
@@ -63,6 +67,8 @@ var ControlledRefreshableListView = React.createClass({
6367
scrollEventThrottle: SCROLL_EVENT_THROTTLE,
6468
ignoreInertialScroll: true,
6569
refreshingIndicatorComponent: RefreshingIndicator,
70+
pullingPrompt: 'Pull to refresh',
71+
holdingPrompt: 'Release to refresh',
6672
}
6773
},
6874
getInitialState() {
@@ -81,9 +87,11 @@ var ControlledRefreshableListView = React.createClass({
8187
if (
8288
this.isReleaseUpdate(this.props, this.state, nextProps, nextState)
8389
) {
84-
this.getScrollResponder().scrollWithoutAnimationTo(
90+
scrollToCompat(
91+
this.getScrollResponder(),
8592
-(this.lastContentInsetTop + REFRESHING_INDICATOR_HEIGHT),
86-
this.lastContentOffsetX
93+
this.lastContentOffsetX,
94+
false
8795
)
8896
}
8997
}
@@ -93,13 +101,18 @@ var ControlledRefreshableListView = React.createClass({
93101
if (
94102
this.isReleaseUpdate(prevProps, prevState, this.props, this.state)
95103
) {
96-
this.getScrollResponder().scrollWithoutAnimationTo(
104+
scrollToCompat(
105+
this.getScrollResponder(),
97106
-(this.lastContentInsetTop),
98-
this.lastContentOffsetX
107+
this.lastContentOffsetX,
108+
false
99109
)
100110
}
101111
}
102112
},
113+
handlePullToRefreshViewAndroidRef(swipeRefreshLayout) {
114+
this.swipeRefreshLayout = swipeRefreshLayout
115+
},
103116
handleScroll(e) {
104117
var scrollY = e.nativeEvent.contentInset.top + e.nativeEvent.contentOffset.y
105118
this.lastScrollY = scrollY
@@ -184,39 +197,56 @@ var ControlledRefreshableListView = React.createClass({
184197
pullingIndicator,
185198
holdingIndicator,
186199
refreshingIndicator,
187-
pullingPrompt: pullingPrompt || 'Pull to refresh',
188-
holdingPrompt: holdingPrompt || 'Release to refresh',
200+
pullingPrompt: pullingPrompt,
201+
holdingPrompt: holdingPrompt,
189202
refreshingPrompt: refreshingPrompt || refreshDescription,
190203
isTouching: this.isTouching,
191204
isWaitingForRelease: this.isWaitingForRelease(),
192205
}
193206
return createElementFrom(this.props.refreshingIndicatorComponent, refreshingIndicatorProps)
194207
},
195208
render() {
196-
return (
197-
<View style={[stylesheet.container]}>
198-
<View style={[stylesheet.fillParent]}>
199-
{this.renderRefreshingIndicator()}
200-
</View>
201-
<View style={[stylesheet.fillParent]}>
209+
if (Platform.OS === 'android') {
210+
return (
211+
<PullToRefreshViewAndroid
212+
ref={this.handlePullToRefreshViewAndroidRef}
213+
onRefresh={this.props.onRefresh}
214+
colors={this.props.colors}
215+
progressBackgroundColor={this.props.progressBackgroundColor}
216+
style={stylesheet.container}
217+
>
202218
<ListView
203219
{...this.props}
204220
ref={LISTVIEW_REF}
205-
contentContainerStyle={this.getContentContainerStyle()}
206-
onScroll={this.handleScroll}
207-
scrollEventThrottle={this.props.scrollEventThrottle}
208-
onResponderGrant={this.handleResponderGrant}
209-
onResponderRelease={this.handleResponderRelease}
210221
/>
222+
</PullToRefreshViewAndroid>
223+
)
224+
} else {
225+
return (
226+
<View style={[stylesheet.container]}>
227+
<View style={[stylesheet.fillParent]}>
228+
{this.renderRefreshingIndicator()}
229+
</View>
230+
<View style={[stylesheet.fillParent]}>
231+
<ListView
232+
{...this.props}
233+
ref={LISTVIEW_REF}
234+
contentContainerStyle={this.getContentContainerStyle()}
235+
onScroll={this.handleScroll}
236+
scrollEventThrottle={this.props.scrollEventThrottle}
237+
onResponderGrant={this.handleResponderGrant}
238+
onResponderRelease={this.handleResponderRelease}
239+
/>
240+
</View>
211241
</View>
212-
</View>
213-
)
242+
)
243+
}
214244
},
215245
})
216246

217247
var stylesheet = StyleSheet.create({
218248
container: {
219-
// flex: 1,
249+
flex: 1,
220250
},
221251
fillParent: {
222252
backgroundColor: 'transparent',
@@ -226,22 +256,6 @@ var stylesheet = StyleSheet.create({
226256
right: 0,
227257
bottom: 0,
228258
},
229-
// offsetParent: {
230-
// position: 'relative',
231-
// },
232-
// positionTopLeft: {
233-
// position: 'absolute',
234-
// top: 0,
235-
// left: 0,
236-
// },
237-
// fill: {
238-
// flex: 1
239-
// },
240-
// center: {
241-
// flex: 1,
242-
// justifyContent: 'space-around',
243-
// alignItems: 'center',
244-
// },
245259
})
246260

247261
module.exports = ControlledRefreshableListView

lib/__mocks__/react-native.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var ReactNative = {
1919
create: (ss) => ss,
2020
},
2121
PropTypes: React.PropTypes,
22+
Platform: {OS: 'ios'},
2223
}
2324

2425
module.exports = ReactNative

lib/scrollToCompat.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
let cachedResult = null
2+
3+
function isLegacyReactNative() {
4+
if (cachedResult == null) {
5+
try {
6+
const PACKAGE = require('../../react-native/package.json')
7+
const version = PACKAGE.version
8+
cachedResult = (
9+
version[0] === '0' &&
10+
parseInt(version.split('.')[1], 10) < 20
11+
)
12+
} catch (err) {
13+
cachedResult = true
14+
}
15+
}
16+
return cachedResult
17+
}
18+
19+
// handle API change in react native 0.20
20+
function scrollToCompat(scrollResponder, y, x, animate = false) {
21+
if (isLegacyReactNative()) {
22+
scrollResponder.scrollTo(y, x, animate)
23+
} else {
24+
scrollResponder.scrollTo({x, y, animate})
25+
}
26+
}
27+
28+
module.exports = scrollToCompat

0 commit comments

Comments
 (0)