11const React = require ( 'react' ) ;
2- const { Component, } = React ;
3- const { ViewPropTypes, } = ReactNative = require ( 'react-native' ) ;
2+ const { Component } = React ;
3+ const { ViewPropTypes } = ReactNative = require ( 'react-native' ) ;
44const createReactClass = require ( 'create-react-class' ) ;
55const PropTypes = require ( 'prop-types' ) ;
66const {
@@ -19,17 +19,13 @@ const SceneComponent = require('./SceneComponent');
1919const DefaultTabBar = require ( './DefaultTabBar' ) ;
2020const ScrollableTabBar = require ( './ScrollableTabBar' ) ;
2121
22- const AnimatedViewPagerAndroid = Platform . OS === 'android' ?
23- Animated . createAnimatedComponent ( ViewPagerAndroid ) :
24- undefined ;
2522
2623const ScrollableTabView = createReactClass ( {
2724 mixins : [ TimerMixin , ] ,
2825 statics : {
2926 DefaultTabBar,
3027 ScrollableTabBar,
3128 } ,
32- scrollOnMountCalled : false ,
3329
3430 propTypes : {
3531 tabBarPosition : PropTypes . oneOf ( [ 'top' , 'bottom' , 'overlayTop' , 'overlayBottom' , ] ) ,
@@ -60,61 +56,14 @@ const ScrollableTabView = createReactClass({
6056 } ,
6157
6258 getInitialState ( ) {
63- const containerWidth = Dimensions . get ( 'window' ) . width ;
64- let scrollValue ;
65- let scrollXIOS ;
66- let positionAndroid ;
67- let offsetAndroid ;
68-
69- if ( Platform . OS === 'ios' ) {
70- scrollXIOS = new Animated . Value ( this . props . initialPage * containerWidth ) ;
71- const containerWidthAnimatedValue = new Animated . Value ( containerWidth ) ;
72- // Need to call __makeNative manually to avoid a native animated bug. See
73- // https://github.com/facebook/react-native/pull/14435
74- containerWidthAnimatedValue . __makeNative ( ) ;
75- scrollValue = Animated . divide ( scrollXIOS , containerWidthAnimatedValue ) ;
76-
77- const callListeners = this . _polyfillAnimatedValue ( scrollValue ) ;
78- scrollXIOS . addListener (
79- ( { value, } ) => callListeners ( value / this . state . containerWidth )
80- ) ;
81- } else {
82- positionAndroid = new Animated . Value ( this . props . initialPage ) ;
83- offsetAndroid = new Animated . Value ( 0 ) ;
84- scrollValue = Animated . add ( positionAndroid , offsetAndroid ) ;
85-
86- const callListeners = this . _polyfillAnimatedValue ( scrollValue ) ;
87- let positionAndroidValue = this . props . initialPage ;
88- let offsetAndroidValue = 0 ;
89- positionAndroid . addListener ( ( { value, } ) => {
90- positionAndroidValue = value ;
91- callListeners ( positionAndroidValue + offsetAndroidValue ) ;
92- } ) ;
93- offsetAndroid . addListener ( ( { value, } ) => {
94- offsetAndroidValue = value ;
95- callListeners ( positionAndroidValue + offsetAndroidValue ) ;
96- } ) ;
97- }
98-
9959 return {
10060 currentPage : this . props . initialPage ,
101- scrollValue,
102- scrollXIOS,
103- positionAndroid,
104- offsetAndroid,
105- containerWidth,
61+ scrollValue : new Animated . Value ( this . props . initialPage ) ,
62+ containerWidth : Dimensions . get ( 'window' ) . width ,
10663 sceneKeys : this . newSceneKeys ( { currentPage : this . props . initialPage , } ) ,
10764 } ;
10865 } ,
109- componentDidMount ( ) {
110- const { initialPage, } = this . props ;
111- requestAnimationFrame ( ( ) => {
112- if ( Platform . OS === 'ios' && initialPage ) {
113- const containerWidth = Dimensions . get ( 'window' ) . width ;
114- this . scrollView . _component . scrollTo ( { y : 0 , x : containerWidth * initialPage , animated : false , } ) ;
115- }
116- } ) ;
117- } ,
66+
11867 componentWillReceiveProps ( props ) {
11968 if ( props . children !== this . props . children ) {
12069 this . updateSceneKeys ( { page : this . state . currentPage , children : props . children , } ) ;
@@ -125,29 +74,10 @@ const ScrollableTabView = createReactClass({
12574 }
12675 } ,
12776
128- componentWillUnmount ( ) {
129- if ( Platform . OS === 'ios' ) {
130- this . state . scrollXIOS . removeAllListeners ( ) ;
131- } else {
132- this . state . positionAndroid . removeAllListeners ( ) ;
133- this . state . offsetAndroid . removeAllListeners ( ) ;
134- }
135- } ,
136-
13777 goToPage ( pageNumber ) {
138- if ( Platform . OS === 'ios' ) {
139- const offset = pageNumber * this . state . containerWidth ;
140- if ( this . scrollView ) {
141- this . scrollView . getNode ( ) . scrollTo ( { x : offset , y : 0 , animated : ! this . props . scrollWithoutAnimation , } ) ;
142- }
143- } else {
144- if ( this . scrollView ) {
145- if ( this . props . scrollWithoutAnimation ) {
146- this . scrollView . getNode ( ) . setPageWithoutAnimation ( pageNumber ) ;
147- } else {
148- this . scrollView . getNode ( ) . setPage ( pageNumber ) ;
149- }
150- }
78+ const offset = pageNumber * this . state . containerWidth ;
79+ if ( this . scrollView ) {
80+ this . scrollView . scrollTo ( { x : offset , y : 0 , animated : ! this . props . scrollWithoutAnimation , } ) ;
15181 }
15282
15383 const currentPage = this . state . currentPage ;
@@ -184,31 +114,6 @@ const ScrollableTabView = createReactClass({
184114 return newKeys ;
185115 } ,
186116
187- // Animated.add and Animated.divide do not currently support listeners so
188- // we have to polyfill it here since a lot of code depends on being able
189- // to add a listener to `scrollValue`. See https://github.com/facebook/react-native/pull/12620.
190- _polyfillAnimatedValue ( animatedValue ) {
191-
192- const listeners = new Set ( ) ;
193- const addListener = ( listener ) => {
194- listeners . add ( listener ) ;
195- } ;
196-
197- const removeListener = ( listener ) => {
198- listeners . delete ( listener ) ;
199- } ;
200-
201- const removeAllListeners = ( ) => {
202- listeners . clear ( ) ;
203- } ;
204-
205- animatedValue . addListener = addListener ;
206- animatedValue . removeListener = removeListener ;
207- animatedValue . removeAllListeners = removeAllListeners ;
208-
209- return ( value ) => listeners . forEach ( listener => listener ( { value, } ) ) ;
210- } ,
211-
212117 _shouldRenderSceneKey ( idx , currentPageKey ) {
213118 let numOfSibling = this . props . prerenderingSiblingsNumber ;
214119 return ( idx < ( currentPageKey + numOfSibling + 1 ) &&
@@ -224,57 +129,30 @@ const ScrollableTabView = createReactClass({
224129 } ,
225130
226131 renderScrollableContent ( ) {
227- if ( Platform . OS === 'ios' ) {
228- const scenes = this . _composeScenes ( ) ;
229- return < Animated . ScrollView
230- horizontal
231- pagingEnabled
232- automaticallyAdjustContentInsets = { false }
233- ref = { ( scrollView ) => { this . scrollView = scrollView ; } }
234- onScroll = { Animated . event (
235- [ { nativeEvent : { contentOffset : { x : this . state . scrollXIOS , } , } , } , ] ,
236- { useNativeDriver : true , listener : this . _onScroll , }
237- ) }
238- onMomentumScrollBegin = { this . _onMomentumScrollBeginAndEnd }
239- onMomentumScrollEnd = { this . _onMomentumScrollBeginAndEnd }
240- scrollEventThrottle = { 16 }
241- scrollsToTop = { false }
242- showsHorizontalScrollIndicator = { false }
243- scrollEnabled = { ! this . props . locked }
244- directionalLockEnabled
245- alwaysBounceVertical = { false }
246- keyboardDismissMode = "on-drag"
247- { ...this . props . contentProps }
248- >
249- { scenes }
250- </ Animated . ScrollView > ;
251- } else {
252- const scenes = this . _composeScenes ( ) ;
253- return < AnimatedViewPagerAndroid
254- key = { this . _children ( ) . length }
255- style = { styles . scrollableContentAndroid }
256- initialPage = { this . props . initialPage }
257- onPageSelected = { this . _updateSelectedPage }
258- keyboardDismissMode = "on-drag"
259- scrollEnabled = { ! this . props . locked }
260- onPageScroll = { Animated . event (
261- [ {
262- nativeEvent : {
263- position : this . state . positionAndroid ,
264- offset : this . state . offsetAndroid ,
265- } ,
266- } , ] ,
267- {
268- useNativeDriver : true ,
269- listener : this . _onScroll ,
270- } ,
271- ) }
272- ref = { ( scrollView ) => { this . scrollView = scrollView ; } }
273- { ...this . props . contentProps }
274- >
275- { scenes }
276- </ AnimatedViewPagerAndroid > ;
277- }
132+ const scenes = this . _composeScenes ( ) ;
133+ return < ScrollView
134+ horizontal
135+ pagingEnabled
136+ automaticallyAdjustContentInsets = { false }
137+ contentOffset = { { x : this . props . initialPage * this . state . containerWidth , } }
138+ ref = { ( scrollView ) => { this . scrollView = scrollView ; } }
139+ onScroll = { ( e ) => {
140+ const offsetX = e . nativeEvent . contentOffset . x ;
141+ this . _updateScrollValue ( offsetX / this . state . containerWidth ) ;
142+ } }
143+ onMomentumScrollBegin = { this . _onMomentumScrollBeginAndEnd }
144+ onMomentumScrollEnd = { this . _onMomentumScrollBeginAndEnd }
145+ scrollEventThrottle = { 16 }
146+ scrollsToTop = { false }
147+ showsHorizontalScrollIndicator = { false }
148+ scrollEnabled = { ! this . props . locked }
149+ directionalLockEnabled
150+ alwaysBounceVertical = { false }
151+ keyboardDismissMode = "on-drag"
152+ { ...this . props . contentProps }
153+ >
154+ { scenes }
155+ </ ScrollView > ;
278156 } ,
279157
280158 _composeScenes ( ) {
@@ -319,40 +197,20 @@ const ScrollableTabView = createReactClass({
319197 } ) ;
320198 } ,
321199
322- _onScroll ( e ) {
323- if ( Platform . OS === 'ios' ) {
324- const offsetX = e . nativeEvent . contentOffset . x ;
325- if ( offsetX === 0 && ! this . scrollOnMountCalled ) {
326- this . scrollOnMountCalled = true ;
327- } else {
328- this . props . onScroll ( offsetX / this . state . containerWidth ) ;
329- }
330- } else {
331- const { position, offset, } = e . nativeEvent ;
332- this . props . onScroll ( position + offset ) ;
333- }
200+ _updateScrollValue ( value ) {
201+ this . state . scrollValue . setValue ( value ) ;
202+ this . props . onScroll ( value ) ;
334203 } ,
335204
336205 _handleLayout ( e ) {
337206 const { width, } = e . nativeEvent . layout ;
338207
339- if ( ! width || width <= 0 || Math . round ( width ) === Math . round ( this . state . containerWidth ) ) {
340- return ;
341- }
342-
343- if ( Platform . OS === 'ios' ) {
344- const containerWidthAnimatedValue = new Animated . Value ( width ) ;
345- // Need to call __makeNative manually to avoid a native animated bug. See
346- // https://github.com/facebook/react-native/pull/14435
347- containerWidthAnimatedValue . __makeNative ( ) ;
348- scrollValue = Animated . divide ( this . state . scrollXIOS , containerWidthAnimatedValue ) ;
349- this . setState ( { containerWidth : width , scrollValue, } ) ;
350- } else {
208+ if ( Math . round ( width ) !== Math . round ( this . state . containerWidth ) ) {
351209 this . setState ( { containerWidth : width , } ) ;
210+ this . requestAnimationFrame ( ( ) => {
211+ this . goToPage ( this . state . currentPage ) ;
212+ } ) ;
352213 }
353- this . requestAnimationFrame ( ( ) => {
354- this . goToPage ( this . state . currentPage ) ;
355- } ) ;
356214 } ,
357215
358216 _children ( children = this . props . children ) {
0 commit comments