diff --git a/index.js b/index.js index af94d866..64d6c5a1 100644 --- a/index.js +++ b/index.js @@ -19,9 +19,6 @@ const SceneComponent = require('./SceneComponent'); const DefaultTabBar = require('./DefaultTabBar'); const ScrollableTabBar = require('./ScrollableTabBar'); -const AnimatedViewPagerAndroid = Platform.OS === 'android' ? - Animated.createAnimatedComponent(ViewPagerAndroid) : - undefined; const ScrollableTabView = createReactClass({ mixins: [TimerMixin, ], @@ -29,7 +26,6 @@ const ScrollableTabView = createReactClass({ DefaultTabBar, ScrollableTabBar, }, - scrollOnMountCalled: false, propTypes: { tabBarPosition: PropTypes.oneOf(['top', 'bottom', 'overlayTop', 'overlayBottom', ]), @@ -60,49 +56,10 @@ const ScrollableTabView = createReactClass({ }, getInitialState() { - const containerWidth = Dimensions.get('window').width; - let scrollValue; - let scrollXIOS; - let positionAndroid; - let offsetAndroid; - - if (Platform.OS === 'ios') { - scrollXIOS = new Animated.Value(this.props.initialPage * containerWidth); - const containerWidthAnimatedValue = new Animated.Value(containerWidth); - // Need to call __makeNative manually to avoid a native animated bug. See - // https://github.com/facebook/react-native/pull/14435 - containerWidthAnimatedValue.__makeNative(); - scrollValue = Animated.divide(scrollXIOS, containerWidthAnimatedValue); - - const callListeners = this._polyfillAnimatedValue(scrollValue); - scrollXIOS.addListener( - ({ value, }) => callListeners(value / this.state.containerWidth) - ); - } else { - positionAndroid = new Animated.Value(this.props.initialPage); - offsetAndroid = new Animated.Value(0); - scrollValue = Animated.add(positionAndroid, offsetAndroid); - - const callListeners = this._polyfillAnimatedValue(scrollValue); - let positionAndroidValue = this.props.initialPage; - let offsetAndroidValue = 0; - positionAndroid.addListener(({ value, }) => { - positionAndroidValue = value; - callListeners(positionAndroidValue + offsetAndroidValue); - }); - offsetAndroid.addListener(({ value, }) => { - offsetAndroidValue = value; - callListeners(positionAndroidValue + offsetAndroidValue); - }); - } - return { currentPage: this.props.initialPage, - scrollValue, - scrollXIOS, - positionAndroid, - offsetAndroid, - containerWidth, + scrollValue: new Animated.Value(this.props.initialPage), + containerWidth: Dimensions.get('window').width, sceneKeys: this.newSceneKeys({ currentPage: this.props.initialPage, }), }; }, @@ -117,29 +74,10 @@ const ScrollableTabView = createReactClass({ } }, - componentWillUnmount() { - if (Platform.OS === 'ios') { - this.state.scrollXIOS.removeAllListeners(); - } else { - this.state.positionAndroid.removeAllListeners(); - this.state.offsetAndroid.removeAllListeners(); - } - }, - goToPage(pageNumber) { - if (Platform.OS === 'ios') { - const offset = pageNumber * this.state.containerWidth; - if (this.scrollView) { - this.scrollView.getNode().scrollTo({x: offset, y: 0, animated: !this.props.scrollWithoutAnimation, }); - } - } else { - if (this.scrollView) { - if (this.props.scrollWithoutAnimation) { - this.scrollView.getNode().setPageWithoutAnimation(pageNumber); - } else { - this.scrollView.getNode().setPage(pageNumber); - } - } + const offset = pageNumber * this.state.containerWidth; + if (this.scrollView) { + this.scrollView.scrollTo({x: offset, y: 0, animated: !this.props.scrollWithoutAnimation, }); } const currentPage = this.state.currentPage; @@ -176,31 +114,6 @@ const ScrollableTabView = createReactClass({ return newKeys; }, - // Animated.add and Animated.divide do not currently support listeners so - // we have to polyfill it here since a lot of code depends on being able - // to add a listener to `scrollValue`. See https://github.com/facebook/react-native/pull/12620. - _polyfillAnimatedValue(animatedValue) { - - const listeners = new Set(); - const addListener = (listener) => { - listeners.add(listener); - }; - - const removeListener = (listener) => { - listeners.delete(listener); - }; - - const removeAllListeners = () => { - listeners.clear(); - }; - - animatedValue.addListener = addListener; - animatedValue.removeListener = removeListener; - animatedValue.removeAllListeners = removeAllListeners; - - return (value) => listeners.forEach(listener => listener({ value, })); - }, - _shouldRenderSceneKey(idx, currentPageKey) { let numOfSibling = this.props.prerenderingSiblingsNumber; return (idx < (currentPageKey + numOfSibling + 1) && @@ -216,58 +129,30 @@ const ScrollableTabView = createReactClass({ }, renderScrollableContent() { - if (Platform.OS === 'ios') { - const scenes = this._composeScenes(); - return { this.scrollView = scrollView; }} - onScroll={Animated.event( - [{ nativeEvent: { contentOffset: { x: this.state.scrollXIOS, }, }, }, ], - { useNativeDriver: true, listener: this._onScroll, } - )} - onMomentumScrollBegin={this._onMomentumScrollBeginAndEnd} - onMomentumScrollEnd={this._onMomentumScrollBeginAndEnd} - scrollEventThrottle={16} - scrollsToTop={false} - showsHorizontalScrollIndicator={false} - scrollEnabled={!this.props.locked} - directionalLockEnabled - alwaysBounceVertical={false} - keyboardDismissMode="on-drag" - {...this.props.contentProps} - > - {scenes} - ; - } else { - const scenes = this._composeScenes(); - return { this.scrollView = scrollView; }} - {...this.props.contentProps} - > - {scenes} - ; - } + const scenes = this._composeScenes(); + return { this.scrollView = scrollView; }} + onScroll={(e) => { + const offsetX = e.nativeEvent.contentOffset.x; + this._updateScrollValue(offsetX / this.state.containerWidth); + }} + onMomentumScrollBegin={this._onMomentumScrollBeginAndEnd} + onMomentumScrollEnd={this._onMomentumScrollBeginAndEnd} + scrollEventThrottle={16} + scrollsToTop={false} + showsHorizontalScrollIndicator={false} + scrollEnabled={!this.props.locked} + directionalLockEnabled + alwaysBounceVertical={false} + keyboardDismissMode="on-drag" + {...this.props.contentProps} + > + {scenes} + ; }, _composeScenes() { @@ -312,40 +197,20 @@ const ScrollableTabView = createReactClass({ }); }, - _onScroll(e) { - if (Platform.OS === 'ios') { - const offsetX = e.nativeEvent.contentOffset.x; - if (offsetX === 0 && !this.scrollOnMountCalled) { - this.scrollOnMountCalled = true; - } else { - this.props.onScroll(offsetX / this.state.containerWidth); - } - } else { - const { position, offset, } = e.nativeEvent; - this.props.onScroll(position + offset); - } + _updateScrollValue(value) { + this.state.scrollValue.setValue(value); + this.props.onScroll(value); }, _handleLayout(e) { const { width, } = e.nativeEvent.layout; - if (!width || width <= 0 || Math.round(width) === Math.round(this.state.containerWidth)) { - return; - } - - if (Platform.OS === 'ios') { - const containerWidthAnimatedValue = new Animated.Value(width); - // Need to call __makeNative manually to avoid a native animated bug. See - // https://github.com/facebook/react-native/pull/14435 - containerWidthAnimatedValue.__makeNative(); - scrollValue = Animated.divide(this.state.scrollXIOS, containerWidthAnimatedValue); - this.setState({ containerWidth: width, scrollValue, }); - } else { + if (Math.round(width) !== Math.round(this.state.containerWidth)) { this.setState({ containerWidth: width, }); + this.requestAnimationFrame(() => { + this.goToPage(this.state.currentPage); + }); } - this.requestAnimationFrame(() => { - this.goToPage(this.state.currentPage); - }); }, _children(children = this.props.children) {