/* * @Author: your name * @Date: 2022-04-20 10:03:13 * @LastEditTime: 2022-04-20 18:25:22 * @LastEditors: Please set LastEditors * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @FilePath: /YMJRN/src/common/headtableview/TabView.tsx */ import React from 'react'; import ReactNative, { Animated } from 'react-native'; interface Props { index: number; isActive: boolean; containerOffsetY: Animated.Value; scrollTopCallback:(y:number) => void; sceneHeight: number; headerHeight: number; } const compose = (WrappedComponent) => { const AnimateTabView = Animated.createAnimatedComponent(WrappedComponent); class TabView extends React.Component { constructor(props: Props) { super(props); this.scrollOffsetY = 0; this.state = { bottomPadding: 0, }; this.mounted = false; } componentDidMount() { this.mounted = true; this.addListener(); } componentWillUnmount() { this.removeListener(); } addListener() { const { containerOffsetY } = this.props; containerOffsetY?.addListener(this.tabViewScrollHandler); } removeListener() { const { containerOffsetY } = this.props; containerOffsetY?.removeListener(this.tabViewScrollHandler); } scrollTo(e) { if (this._scrollViewRef) { if (this._scrollViewRef?.scrollTo) { this._scrollViewRef.scrollTo({ x: 0, y: e.y, animated: false }); } else if (this._scrollViewRef?.scrollToOffset) { this._scrollViewRef.scrollToOffset({ offset: e.y, animated: false }); } } } // other TabView sync OffsetY tabViewScrollHandler = (e) => { const { headerHeight, isActive } = this.props; console.log("tabViewScrollHandler",e.value); if (e.value<=0) { this.props.scrollTopCallback&&this.props.scrollTopCallback(e.value) } if (!isActive) { if (e.value > headerHeight && this.scrollOffsetY < headerHeight) { this.scrollTo({ y: headerHeight }); } else { this.scrollTo({ y: e.value }); } } }; // contentHeight changed,adjust offset adjustScrollOffset = () => { if (this.mounted) { this.mounted = false; const { containerOffsetY, headerHeight } = this.props; const scrollValue = containerOffsetY._value > headerHeight ? headerHeight : containerOffsetY._value; this.scrollTo({ y: scrollValue }); } }; // calculate the bottom occupancy height onContentSizeChange = (contentWidth, contentHeight) => { const { bottomPadding } = this.state; const { headerHeight, sceneHeight } = this.props; const remainingHeight = contentHeight - sceneHeight; if (bottomPadding <= 0) { const makePaddingBottom = sceneHeight - contentHeight; this.setState({ bottomPadding: makePaddingBottom }); } else if (remainingHeight > 1) { // The content height exceeds the container height,adjust Tab Offset,and reduce excess occupancy bottomPadding this.adjustScrollOffset(); const newBottomPadding = remainingHeight > bottomPadding ? 0 : bottomPadding - remainingHeight; if (newBottomPadding != bottomPadding) { this.setState({ bottomPadding: newBottomPadding }); } } }; getScrollListener = (isActive) => { if (isActive) { return Animated.event([{ nativeEvent: { contentOffset: { y: this.props.containerOffsetY } } }], { useNativeDriver: true, listener: this.onScroll, }); } else { return this.onScroll; } }; onScroll = (e) => { this.scrollOffsetY = e.nativeEvent.contentOffset.y; }; scrollToIndex = (e) => { this._scrollViewRef&&this._scrollViewRef.scrollToIndex(e); }; render() { const { isActive, children, headerHeight, forwardedRef, contentContainerStyle, custref,...restProps } = this.props; const { bottomPadding } = this.state; const scrollListener = this.getScrollListener(isActive); return ( { this._scrollViewRef = ref; if (forwardedRef) { if (forwardedRef instanceof Function) { forwardedRef(ref); } else if (typeof forwardedRef === 'object' && forwardedRef.hasOwnProperty('current')) { forwardedRef.current = ref; } } if (custref&&typeof(custref)=="function") { custref(this); } }} onScroll={scrollListener} onContentSizeChange={this.onContentSizeChange} contentContainerStyle={{ ...contentContainerStyle, paddingTop: headerHeight, paddingBottom: bottomPadding, }} overScrollMode="never" scrollEventThrottle={16} directionalLockEnabled={true} showsVerticalScrollIndicator={false} automaticallyAdjustContentInsets={false} {...restProps}> {children} ); } } return React.forwardRef((props, ref) => { return ; }); }; export const FlatList = compose(ReactNative.FlatList); export const ScrollView = compose(ReactNative.ScrollView);