UNPKG

react-native-mjrefresh

Version:

>React-Native-MJRefresh可完成使用React Native对IOS进行自定义下拉刷新设置 > >onPulling参数为{nativeEvent:percent},结合lottie-react-native可以获得绝佳的下拉刷新效果 > >自定义详情可见Example:[HuaWeiRefreshControl.js](https://github.com/react-native-studio/react-native-MJRefresh/blob/master/Example/H

225 lines (211 loc) 10.3 kB
import React,{Component} from 'react'; import { requireNativeComponent, ScrollView, View, Platform, StyleSheet, } from 'react-native'; const warning = require('fbjs/lib/warning'); const flattenStyle = require('react-native/Libraries/StyleSheet/flattenStyle'); const invariant = require('fbjs/lib/invariant'); const ScrollViewStickyHeader = require('react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader'); const processDecelerationRate = require('react-native/Libraries/Components/ScrollView/processDecelerationRate'); const RCTMJScrollView = requireNativeComponent('RCTMJScrollView', MJScrollView, { nativeOnly: { onMomentumScrollBegin: true, onMomentumScrollEnd : true, onScrollBeginDrag: true, onScrollEndDrag: true, } }) const RCTMJScrollContentView = requireNativeComponent('RCTMJScrollContentView', View) class MJScrollView extends ScrollView { render() { let ScrollViewClass = RCTMJScrollView; let ScrollContentContainerViewClass = RCTMJScrollContentView; warning( !this.props.snapToInterval || !this.props.pagingEnabled, 'snapToInterval is currently ignored when pagingEnabled is true.' ); invariant( ScrollViewClass !== undefined, 'ScrollViewClass must not be undefined' ); invariant( ScrollContentContainerViewClass !== undefined, 'ScrollContentContainerViewClass must not be undefined' ); const contentContainerStyle = [ this.props.horizontal && styles.contentContainerHorizontal, this.props.contentContainerStyle, ]; let style, childLayoutProps; if (__DEV__ && this.props.style) { style = flattenStyle(this.props.style); childLayoutProps = ['alignItems', 'justifyContent'] .filter((prop) => style && style[prop] !== undefined); invariant( childLayoutProps.length === 0, 'ScrollView child layout (' + JSON.stringify(childLayoutProps) + ') must be applied through the contentContainerStyle prop.' ); } let contentSizeChangeProps = {}; if (this.props.onContentSizeChange) { contentSizeChangeProps = { onLayout: this._handleContentOnLayout, }; } const {stickyHeaderIndices} = this.props; const hasStickyHeaders = stickyHeaderIndices && stickyHeaderIndices.length > 0; /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This comment * suppresses an error when upgrading Flow's support for React. To see the * error delete this comment and run Flow. */ const childArray = hasStickyHeaders && React.Children.toArray(this.props.children); const children = hasStickyHeaders ? /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This * comment suppresses an error when upgrading Flow's support for React. * To see the error delete this comment and run Flow. */ childArray.map((child, index) => { /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This * comment suppresses an error when upgrading Flow's support for React. * To see the error delete this comment and run Flow. */ const indexOfIndex = child ? stickyHeaderIndices.indexOf(index) : -1; if (indexOfIndex > -1) { const key = child.key; /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This * comment suppresses an error when upgrading Flow's support for * React. To see the error delete this comment and run Flow. */ const nextIndex = stickyHeaderIndices[indexOfIndex + 1]; return ( <ScrollViewStickyHeader key={key} ref={(ref) => this._setStickyHeaderRef(key, ref)} nextHeaderLayoutY={ /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) * This comment suppresses an error when upgrading Flow's * support for React. To see the error delete this comment and * run Flow. */ this._headerLayoutYs.get(this._getKeyForIndex(nextIndex, childArray)) } onLayout={(event) => this._onStickyHeaderLayout(index, event, key)} scrollAnimatedValue={this._scrollAnimatedValue}> {child} </ScrollViewStickyHeader> ); } else { return child; } }) : /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This * comment suppresses an error when upgrading Flow's support for React. * To see the error delete this comment and run Flow. */ this.props.children; const contentContainer = <ScrollContentContainerViewClass {...contentSizeChangeProps} /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This * comment suppresses an error when upgrading Flow's support for React. * To see the error delete this comment and run Flow. */ ref={this._setInnerViewRef} style={contentContainerStyle} removeClippedSubviews={ // Subview clipping causes issues with sticky headers on Android and // would be hard to fix properly in a performant way. Platform.OS === 'android' && hasStickyHeaders ? false : this.props.removeClippedSubviews } collapsable={false}> {children} </ScrollContentContainerViewClass>; const alwaysBounceHorizontal = this.props.alwaysBounceHorizontal !== undefined ? this.props.alwaysBounceHorizontal : this.props.horizontal; const alwaysBounceVertical = this.props.alwaysBounceVertical !== undefined ? this.props.alwaysBounceVertical : !this.props.horizontal; const DEPRECATED_sendUpdatedChildFrames = !!this.props.DEPRECATED_sendUpdatedChildFrames; const baseStyle = this.props.horizontal ? styles.baseHorizontal : styles.baseVertical; const props = { ...this.props, alwaysBounceHorizontal, alwaysBounceVertical, style: [baseStyle, this.props.style], // Override the onContentSizeChange from props, since this event can // bubble up from TextInputs onContentSizeChange: null, onMomentumScrollBegin: this.scrollResponderHandleMomentumScrollBegin, onMomentumScrollEnd: this.scrollResponderHandleMomentumScrollEnd, onResponderGrant: this.scrollResponderHandleResponderGrant, onResponderReject: this.scrollResponderHandleResponderReject, onResponderRelease: this.scrollResponderHandleResponderRelease, /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This * comment suppresses an error when upgrading Flow's support for React. * To see the error delete this comment and run Flow. */ onResponderTerminate: this.scrollResponderHandleTerminate, onResponderTerminationRequest: this.scrollResponderHandleTerminationRequest, onScroll: this._handleScroll, onScrollBeginDrag: this.scrollResponderHandleScrollBeginDrag, onScrollEndDrag: this.scrollResponderHandleScrollEndDrag, onScrollShouldSetResponder: this.scrollResponderHandleScrollShouldSetResponder, onStartShouldSetResponder: this.scrollResponderHandleStartShouldSetResponder, onStartShouldSetResponderCapture: this.scrollResponderHandleStartShouldSetResponderCapture, onTouchEnd: this.scrollResponderHandleTouchEnd, onTouchMove: this.scrollResponderHandleTouchMove, onTouchStart: this.scrollResponderHandleTouchStart, scrollEventThrottle: hasStickyHeaders ? 1 : this.props.scrollEventThrottle, sendMomentumEvents: (this.props.onMomentumScrollBegin || this.props.onMomentumScrollEnd) ? true : false, DEPRECATED_sendUpdatedChildFrames, }; const { decelerationRate } = this.props; if (decelerationRate) { props.decelerationRate = processDecelerationRate(decelerationRate); } const refreshControl = this.props.refreshControl; if (refreshControl) { // On iOS the RefreshControl is a child of the ScrollView. // tvOS lacks native support for RefreshControl, so don't include it in that case return ( /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This * comment suppresses an error when upgrading Flow's support for * React. To see the error delete this comment and run Flow. */ <ScrollViewClass {...props} ref={this._setScrollViewRef}> {Platform.isTVOS ? null : refreshControl} {contentContainer} </ScrollViewClass> ); } return ( /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This * comment suppresses an error when upgrading Flow's support for React. * To see the error delete this comment and run Flow. */ <ScrollViewClass {...props} ref={this._setScrollViewRef}> {contentContainer} </ScrollViewClass> ); } } const styles = StyleSheet.create({ baseVertical: { flexGrow: 1, flexShrink: 1, flexDirection: 'column', overflow: 'scroll', }, baseHorizontal: { flexGrow: 1, flexShrink: 1, flexDirection: 'row', overflow: 'scroll', }, contentContainerHorizontal: { flexDirection: 'row', }, }); module.exports = Platform.OS === 'ios' ? MJScrollView : ScrollView