/** * Author: Shi(bolan0000@icloud.com) * Date: 2019/1/17 * Copyright (c) 2018, AoTang, Inc. * * Description: */ import * as React from "react"; import { Animated, requireNativeComponent, View, findNodeHandle, UIManager, Keyboard, Platform, NativeModules, StyleSheet, ViewProps, ViewStyle, ScrollView, } from "react-native"; import { SpringScrollViewNativeAdapter, SpringScrollContentViewNative, } from "./SpringScrollViewNative"; import { FooterStatus } from "./LoadingFooter"; import { NormalHeader } from "./NormalHeader"; import { NormalFooter } from "./NormalFooter"; import type { HeaderStatus } from "./RefreshHeader"; import { idx } from "./idx"; import type { Offset, SpringScrollViewPropType } from "./Types"; import { styles } from "./styles"; export class SpringScrollView extends React.PureComponent { _contentOffset: Offset = { x: 0, y: 0 }; _keyboardHeight: number; _refreshHeader; _loadingFooter; _width: number; _height: number; _scrollView: View; _indicatorOpacity: Animated.Value = new Animated.Value(1); _contentHeight: number; _contentWidth: number; _refreshStatus: HeaderStatus = "waiting"; _loadingStatus: FooterStatus = "waiting"; _indicatorAnimation; _scrollEventAttachment; _nativeOffset; _touching = false; _dragging = false; _sizeChangeInterval = 0; constructor(props) { super(props); this._nativeOffset = { x: new Animated.Value(0), y: new Animated.Value(0), ...props.onNativeContentOffsetExtract, }; this._nativeOffset.x.setValue(props.initialContentOffset.y); this._nativeOffset.y.setValue(props.initialContentOffset.y); } render() { const { style, inverted, children, onRefresh, onLoading, refreshHeader: Refresh, loadingFooter: Loading, } = this.props; const wStyle = StyleSheet.flatten([ styles.wrapperStyle, style, { transform: inverted ? [{ scaleY: -1 }] : [] }, ]); const contentStyle = StyleSheet.flatten([ styles.contentStyle, this.props.contentStyle, ]); return ( (this._scrollView = ref)} style={wStyle} onScroll={this._onScroll} refreshHeaderHeight={onRefresh ? Refresh.height : 0} loadingFooterHeight={onLoading ? Loading.height : 0} onLayout={this._onWrapperLayoutChange} onTouchBegin={this._onTouchBegin} onScrollBeginDrag={this._onScrollBeginDrag} onMomentumScrollEnd={this._onMomentumScrollEnd} scrollEventThrottle={1} onStartShouldSetResponderCapture={() => this._dragging} > {this._renderRefreshHeader()} {this._renderLoadingFooter()} {children} {this._renderHorizontalIndicator()} {this._renderVerticalIndicator()} ); } _renderRefreshHeader() { const { onRefresh, refreshHeader: Refresh } = this.props; const measured = this._height !== undefined && this._contentHeight !== undefined; if (!measured) return null; return ( onRefresh && ( (this._refreshHeader = ref)} offset={this._nativeOffset.y} maxHeight={Refresh.height} /> ) ); } _renderLoadingFooter() { const { onLoading, loadingFooter: Footer } = this.props; const measured = this._height !== undefined && this._contentHeight !== undefined; if (!measured) return null; return ( onLoading && (