Skip to content

Instantly share code, notes, and snippets.

@mijia
Created April 17, 2015 04:37
Show Gist options
  • Save mijia/14d8a9f2668a0f870b15 to your computer and use it in GitHub Desktop.
Save mijia/14d8a9f2668a0f870b15 to your computer and use it in GitHub Desktop.
Pull-to-refreshable list view and scroll view using a mixin
"use strict";
var React = require("react-native");
var {ListView, ScrollView, ActivityIndicatorIOS, View, Text} = React;
var TimerMixin = require("react-timer-mixin");
var kPulldownDistance = 60;
// Working with the TimerMixin, e.g.
// mixins: [TimerMinx, RefreshableMixin]
var RefreshableMixin = {
getDefaultProps() {
return {
minShowingTimeout: 500,
};
},
getInitialState() {
return {
isLoading: false,
};
},
onScroll(evt) {
var lastY = this.lastY ? this.lastY : 0;
var yOffset = evt.nativeEvent.contentOffset.y;
if (yOffset < -kPulldownDistance) {
if (yOffset < lastY) {
this.refresh();
}
this.lastY = yOffset;
}
this.props.onScroll && this.props.onScroll(e);
},
refresh() {
if (this.willReload || this.state.isLoading) {
return;
}
this.willReload = true;
Promise.all([
new Promise((resolve) => this.setState({ isLoading: true }, resolve)),
new Promise((resolve) => this.setTimeout(resolve, this.props.minShowingTimeout)),
]).then(() => {
new Promise((resolve) => this.props.refresh(resolve))
.then(() => {
this.willReload = false;
this.setState({ isLoading: false })
});
});
},
renderHeader() {
if (this.state.isLoading) {
return (
<View style={[styles.container, styles.wrapper]}>
<View style={[styles.container]}>
<ActivityIndicatorIOS />
</View>
</View>
);
} else {
return null;
}
},
};
var RefreshableScrollView = React.createClass({
mixins: [TimerMixin, RefreshableMixin],
render() {
return (
<ScrollView {...this.props}
onScroll={this.onScroll}
scrollEventThrottle={kPulldownDistance}>
{ this.renderHeader() }
{ this.props.children }
</ScrollView>
);
},
});
var RefreshableListView = React.createClass({
mixins: [TimerMixin, RefreshableMixin],
render() {
return (
<ListView {...this.props}
onScroll={this.onScroll}
scrollEventThrottle={kPulldownDistance}
renderHeader={this.renderHeader} />
);
},
});
var styles = React.StyleSheet.create({
wrapper: {
marginTop: 15,
},
container: {
flex: 1,
justifyContent: 'space-around',
alignItems: 'center',
},
});
module.exports = {
RefreshableListView: RefreshableListView,
RefreshableScrollView: RefreshableScrollView,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment