Skip to content

Commit 0d9f504

Browse files
committed
remove view pager, allowing this component placed inside View or ScrollView in Android
1 parent 74a0b3f commit 0d9f504

File tree

2 files changed

+1441
-128
lines changed

2 files changed

+1441
-128
lines changed

index.js

+54-128
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
const 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');
44
const createReactClass = require('create-react-class');
55
const PropTypes = require('prop-types');
66
const {
77
Dimensions,
88
View,
99
Animated,
1010
ScrollView,
11-
Platform,
1211
StyleSheet,
13-
ViewPagerAndroid,
1412
InteractionManager,
1513
} = ReactNative;
1614
const TimerMixin = require('react-timer-mixin');
@@ -19,9 +17,6 @@ const SceneComponent = require('./SceneComponent');
1917
const DefaultTabBar = require('./DefaultTabBar');
2018
const ScrollableTabBar = require('./ScrollableTabBar');
2119

22-
const AnimatedViewPagerAndroid = Platform.OS === 'android' ?
23-
Animated.createAnimatedComponent(ViewPagerAndroid) :
24-
undefined;
2520

2621
const ScrollableTabView = createReactClass({
2722
mixins: [TimerMixin, ],
@@ -66,35 +61,17 @@ const ScrollableTabView = createReactClass({
6661
let positionAndroid;
6762
let offsetAndroid;
6863

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-
}
64+
scrollXIOS = new Animated.Value(this.props.initialPage * containerWidth);
65+
const containerWidthAnimatedValue = new Animated.Value(containerWidth);
66+
// Need to call __makeNative manually to avoid a native animated bug. See
67+
// https://github.com/facebook/react-native/pull/14435
68+
containerWidthAnimatedValue.__makeNative();
69+
scrollValue = Animated.divide(scrollXIOS, containerWidthAnimatedValue);
70+
71+
const callListeners = this._polyfillAnimatedValue(scrollValue);
72+
scrollXIOS.addListener(
73+
({ value, }) => callListeners(value / this.state.containerWidth)
74+
);
9875

9976
return {
10077
currentPage: this.props.initialPage,
@@ -118,28 +95,13 @@ const ScrollableTabView = createReactClass({
11895
},
11996

12097
componentWillUnmount() {
121-
if (Platform.OS === 'ios') {
122-
this.state.scrollXIOS.removeAllListeners();
123-
} else {
124-
this.state.positionAndroid.removeAllListeners();
125-
this.state.offsetAndroid.removeAllListeners();
126-
}
98+
this.state.scrollXIOS.removeAllListeners();
12799
},
128100

129101
goToPage(pageNumber) {
130-
if (Platform.OS === 'ios') {
131-
const offset = pageNumber * this.state.containerWidth;
132-
if (this.scrollView) {
133-
this.scrollView.getNode().scrollTo({x: offset, y: 0, animated: !this.props.scrollWithoutAnimation, });
134-
}
135-
} else {
136-
if (this.scrollView) {
137-
if (this.props.scrollWithoutAnimation) {
138-
this.scrollView.getNode().setPageWithoutAnimation(pageNumber);
139-
} else {
140-
this.scrollView.getNode().setPage(pageNumber);
141-
}
142-
}
102+
const offset = pageNumber * this.state.containerWidth;
103+
if (this.scrollView) {
104+
this.scrollView.getNode().scrollTo({x: offset, y: 0, animated: !this.props.scrollWithoutAnimation, });
143105
}
144106

145107
const currentPage = this.state.currentPage;
@@ -216,70 +178,42 @@ const ScrollableTabView = createReactClass({
216178
},
217179

218180
renderScrollableContent() {
219-
if (Platform.OS === 'ios') {
220-
const scenes = this._composeScenes();
221-
return <Animated.ScrollView
222-
horizontal
223-
pagingEnabled
224-
automaticallyAdjustContentInsets={false}
225-
contentOffset={{ x: this.props.initialPage * this.state.containerWidth, }}
226-
ref={(scrollView) => { this.scrollView = scrollView; }}
227-
onScroll={Animated.event(
228-
[{ nativeEvent: { contentOffset: { x: this.state.scrollXIOS, }, }, }, ],
229-
{ useNativeDriver: true, listener: this._onScroll, }
230-
)}
231-
onMomentumScrollBegin={this._onMomentumScrollBeginAndEnd}
232-
onMomentumScrollEnd={this._onMomentumScrollBeginAndEnd}
233-
scrollEventThrottle={16}
234-
scrollsToTop={false}
235-
showsHorizontalScrollIndicator={false}
236-
scrollEnabled={!this.props.locked}
237-
directionalLockEnabled
238-
alwaysBounceVertical={false}
239-
keyboardDismissMode="on-drag"
240-
{...this.props.contentProps}
241-
>
242-
{scenes}
243-
</Animated.ScrollView>;
244-
} else {
245-
const scenes = this._composeScenes();
246-
return <AnimatedViewPagerAndroid
247-
key={this._children().length}
248-
style={styles.scrollableContentAndroid}
249-
initialPage={this.props.initialPage}
250-
onPageSelected={this._updateSelectedPage}
251-
keyboardDismissMode="on-drag"
252-
scrollEnabled={!this.props.locked}
253-
onPageScroll={Animated.event(
254-
[{
255-
nativeEvent: {
256-
position: this.state.positionAndroid,
257-
offset: this.state.offsetAndroid,
258-
},
259-
}, ],
260-
{
261-
useNativeDriver: true,
262-
listener: this._onScroll,
263-
},
264-
)}
265-
ref={(scrollView) => { this.scrollView = scrollView; }}
266-
{...this.props.contentProps}
267-
>
181+
const scenes = this._composeScenes();
182+
return (<Animated.ScrollView
183+
horizontal
184+
pagingEnabled
185+
automaticallyAdjustContentInsets={false}
186+
contentOffset={{ x: this.props.initialPage * this.state.containerWidth, }}
187+
ref={(scrollView) => { this.scrollView = scrollView; }}
188+
onScroll={Animated.event(
189+
[{ nativeEvent: { contentOffset: { x: this.state.scrollXIOS, }, }, }, ],
190+
{ useNativeDriver: true, listener: this._onScroll, }
191+
)}
192+
onMomentumScrollBegin={this._onMomentumScrollBeginAndEnd}
193+
onMomentumScrollEnd={this._onMomentumScrollBeginAndEnd}
194+
scrollEventThrottle={16}
195+
scrollsToTop={false}
196+
showsHorizontalScrollIndicator={false}
197+
scrollEnabled={!this.props.locked}
198+
directionalLockEnabled
199+
alwaysBounceVertical={false}
200+
keyboardDismissMode="on-drag"
201+
{...this.props.contentProps}
202+
>
268203
{scenes}
269-
</AnimatedViewPagerAndroid>;
270-
}
204+
</Animated.ScrollView>);
271205
},
272206

273207
_composeScenes() {
274208
return this._children().map((child, idx) => {
275209
let key = this._makeSceneKey(child, idx);
276-
return <SceneComponent
210+
return (<SceneComponent
277211
key={child.key}
278212
shouldUpdated={this._shouldRenderSceneKey(idx, this.state.currentPage)}
279213
style={{width: this.state.containerWidth, }}
280214
>
281215
{this._keyExists(this.state.sceneKeys, key) ? child : <View tabLabel={child.props.tabLabel}/>}
282-
</SceneComponent>;
216+
</SceneComponent>);
283217
});
284218
},
285219

@@ -313,16 +247,11 @@ const ScrollableTabView = createReactClass({
313247
},
314248

315249
_onScroll(e) {
316-
if (Platform.OS === 'ios') {
317-
const offsetX = e.nativeEvent.contentOffset.x;
318-
if (offsetX === 0 && !this.scrollOnMountCalled) {
319-
this.scrollOnMountCalled = true;
320-
} else {
321-
this.props.onScroll(offsetX / this.state.containerWidth);
322-
}
250+
const offsetX = e.nativeEvent.contentOffset.x;
251+
if (offsetX === 0 && !this.scrollOnMountCalled) {
252+
this.scrollOnMountCalled = true;
323253
} else {
324-
const { position, offset, } = e.nativeEvent;
325-
this.props.onScroll(position + offset);
254+
this.props.onScroll(offsetX / this.state.containerWidth);
326255
}
327256
},
328257

@@ -332,17 +261,14 @@ const ScrollableTabView = createReactClass({
332261
if (!width || width <= 0 || Math.round(width) === Math.round(this.state.containerWidth)) {
333262
return;
334263
}
335-
336-
if (Platform.OS === 'ios') {
337-
const containerWidthAnimatedValue = new Animated.Value(width);
338-
// Need to call __makeNative manually to avoid a native animated bug. See
339-
// https://github.com/facebook/react-native/pull/14435
340-
containerWidthAnimatedValue.__makeNative();
341-
scrollValue = Animated.divide(this.state.scrollXIOS, containerWidthAnimatedValue);
342-
this.setState({ containerWidth: width, scrollValue, });
343-
} else {
344-
this.setState({ containerWidth: width, });
345-
}
264+
265+
const containerWidthAnimatedValue = new Animated.Value(width);
266+
// Need to call __makeNative manually to avoid a native animated bug. See
267+
// https://github.com/facebook/react-native/pull/14435
268+
containerWidthAnimatedValue.__makeNative();
269+
scrollValue = Animated.divide(this.state.scrollXIOS, containerWidthAnimatedValue);
270+
this.setState({ containerWidth: width, scrollValue, });
271+
346272
this.requestAnimationFrame(() => {
347273
this.goToPage(this.state.currentPage);
348274
});

0 commit comments

Comments
 (0)