UNPKG

react-native-refresh-control-wd

Version:
221 lines (203 loc) 5.74 kB
/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule RefreshControlExpand * @flow */ 'use strict'; import React from 'react'; import { ColorPropType, NativeMethodsMixin, Platform, ViewPropTypes, requireNativeComponent, UIManager } from 'react-native'; import PropTypes from 'prop-types'; import createReactClass from 'create-react-class'; if (Platform.OS === 'android') { var RefreshLayoutConsts = UIManager.AndroidSwipeRefreshLayout.Constants; } else { var RefreshLayoutConsts = {SIZE: {}}; } /** * This component is used inside a ScrollView or ListView to add pull to refresh * functionality. When the ScrollView is at `scrollY: 0`, swiping down * triggers an `onRefresh` event. * * ### Usage example * * ``` js * class RefreshableList extends Component { * constructor(props) { * super(props); * this.state = { * refreshing: false, * }; * } * * _onRefresh() { * this.setState({refreshing: true}); * fetchData().then(() => { * this.setState({refreshing: false}); * }); * } * * render() { * return ( * <ListView * refreshControl={ * <RefreshControl * refreshing={this.state.refreshing} * onRefresh={this._onRefresh.bind(this)} * /> * } * ... * > * ... * </ListView> * ); * } * ... * } * ``` * * __Note:__ `refreshing` is a controlled prop, this is why it needs to be set to true * in the `onRefresh` function otherwise the refresh indicator will stop immediately. */ // $FlowFixMe(>=0.41.0) const RefreshControlExpand = createReactClass({ displayName: 'RefreshControlExpand', statics: { SIZE: RefreshLayoutConsts.SIZE, }, mixins: [NativeMethodsMixin], propTypes: { ...ViewPropTypes, /** * Called when the view starts refreshing. */ onRefresh: PropTypes.func, /** * Whether the view should be indicating an active refresh. */ refreshing: PropTypes.bool.isRequired, /** * android * Called when the view pull distance */ onPullDistance: PropTypes.func, /** * android * Called when the view pull enable */ onPullEnable: PropTypes.func, /** * android * Set the distance to trigger a sync in dips */ distance: PropTypes.number, /** * change default head view * type: ['test', 'default'] */ changeDefaultHead: PropTypes.string, /** * The color of the refresh indicator. * @platform ios */ tintColor: ColorPropType, /** * Title color. * @platform ios */ titleColor: ColorPropType, /** * The title displayed under the refresh indicator. * @platform ios */ title: PropTypes.string, /** * Whether the pull to refresh functionality is enabled. * @platform android */ enabled: PropTypes.bool, /** * The colors (at least one) that will be used to draw the refresh indicator. * @platform android */ colors: PropTypes.arrayOf(ColorPropType), /** * The background color of the refresh indicator. * @platform android */ progressBackgroundColor: ColorPropType, /** * Size of the refresh indicator, see RefreshControl.SIZE. * @platform android */ size: PropTypes.oneOf([RefreshLayoutConsts.SIZE.DEFAULT, RefreshLayoutConsts.SIZE.LARGE]), /** * Progress view top offset * @platform android */ // progressViewOffset: PropTypes.number, }, _nativeRef: (null: any), _lastNativeRefreshing: false, componentDidMount() { this._lastNativeRefreshing = this.props.refreshing; }, componentDidUpdate(prevProps: {refreshing: boolean, loadmore: boolean}) { // RefreshControl is a controlled component so if the native refreshing // value doesn't match the current js refreshing prop update it to // the js value. if (this.props.refreshing !== prevProps.refreshing) { this._lastNativeRefreshing = this.props.refreshing; } else if (this.props.refreshing !== this._lastNativeRefreshing) { this._nativeRef.setNativeProps({refreshing: this.props.refreshing}); this._lastNativeRefreshing = this.props.refreshing; } }, render() { return ( <NativeRefreshControl {...this.props} ref={ref => {this._nativeRef = ref;}} onRefresh={this._onRefresh} onPullDistance={this._onPullDistance} onPullEnable={this._onPullEnable} /> ); }, _onRefresh() { this._lastNativeRefreshing = true; this.props.onRefresh && this.props.onRefresh(); // The native component will start refreshing so force an update to // make sure it stays in sync with the js component. this.forceUpdate(); }, _onPullDistance(event: Event) { if (!this.props.onPullDistance) { return; } this.props.onPullDistance(event.nativeEvent.distance); }, _onPullEnable(event: Event) { if (!this.props.onPullEnable) { return; } this.props.onPullEnable(event.nativeEvent.enable); }, }); if (Platform.OS === 'ios') { var NativeRefreshControl = requireNativeComponent( 'RCTRefreshControl', RefreshControlExpand ); } else if (Platform.OS === 'android') { var NativeRefreshControl = requireNativeComponent( 'AndroidSuperSwipeRefreshLayout', RefreshControlExpand ); } module.exports = RefreshControlExpand;