Skip to content

Commit f8d66f3

Browse files
feat(pages): support optionally render page (#1009)
* feat(pages): support optionally render page re #1004 * fix(ScrollView): android ScrollView will not scrollTo certain offset when props change
1 parent 655eb20 commit f8d66f3

File tree

2 files changed

+59
-61
lines changed

2 files changed

+59
-61
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"react-native",
66
"ios"
77
],
8-
"version": "1.6.0-nightly.1",
8+
"version": "1.6.0-nightly.2",
99
"description": "Swiper component for React Native.",
1010
"main": "index.js",
1111
"scripts": {

src/index.js

Lines changed: 58 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import {
1515
ActivityIndicator
1616
} from 'react-native'
1717

18-
import ViewPagerAndroid from '@react-native-community/viewpager'
19-
2018
/**
2119
* Default styles
2220
* @type {StyleSheetPropType}
@@ -129,8 +127,16 @@ export default class extends Component {
129127
autoplayDirection: PropTypes.bool,
130128
index: PropTypes.number,
131129
renderPagination: PropTypes.func,
132-
dotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]),
133-
activeDotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]),
130+
dotStyle: PropTypes.oneOfType([
131+
PropTypes.object,
132+
PropTypes.number,
133+
PropTypes.array
134+
]),
135+
activeDotStyle: PropTypes.oneOfType([
136+
PropTypes.object,
137+
PropTypes.number,
138+
PropTypes.array
139+
]),
134140
dotColor: PropTypes.string,
135141
activeDotColor: PropTypes.string,
136142
/**
@@ -215,6 +221,11 @@ export default class extends Component {
215221
if (this.props.autoplay && !prevProps.autoplay) {
216222
this.autoplay()
217223
}
224+
if (this.props.children !== prevProps.children) {
225+
this.setState(
226+
this.initState({ ...this.props, index: this.state.index }, true)
227+
)
228+
}
218229
}
219230

220231
initState(props, updateIndex = false) {
@@ -223,11 +234,15 @@ export default class extends Component {
223234

224235
const initState = {
225236
autoplayEnd: false,
237+
children: null,
226238
loopJump: false,
227239
offset: {}
228240
}
229241

230-
initState.total = props.children ? props.children.length || 1 : 0
242+
// Support Optional render page
243+
initState.children = props.children.filter(child => child)
244+
245+
initState.total = initState.children ? initState.children.length || 1 : 0
231246

232247
if (state.total === initState.total && !updateIndex) {
233248
// retain the index
@@ -300,11 +315,9 @@ export default class extends Component {
300315
// related to https://github.com/leecade/react-native-swiper/issues/570
301316
// contentOffset is not working in react 0.48.x so we need to use scrollTo
302317
// to emulate offset.
303-
if (Platform.OS === 'ios') {
304-
if (this.initialRender && this.state.total > 1) {
305-
this.scrollView.scrollTo({ ...offset, animated: false })
306-
this.initialRender = false
307-
}
318+
if (this.initialRender && this.state.total > 1) {
319+
this.scrollView.scrollTo({ ...offset, animated: false })
320+
this.initialRender = false
308321
}
309322

310323
this.setState(state)
@@ -327,7 +340,7 @@ export default class extends Component {
327340
*/
328341
autoplay = () => {
329342
if (
330-
!Array.isArray(this.props.children) ||
343+
!Array.isArray(this.state.children) ||
331344
!this.props.autoplay ||
332345
this.internals.isScrolling ||
333346
this.state.autoplayEnd
@@ -396,8 +409,8 @@ export default class extends Component {
396409
*/
397410
onScrollEndDrag = e => {
398411
const { contentOffset } = e.nativeEvent
399-
const { horizontal, children } = this.props
400-
const { index } = this.state
412+
const { horizontal } = this.props
413+
const { children, index } = this.state
401414
const { offset } = this.internals
402415
const previousOffset = horizontal ? offset.x : offset.y
403416
const newOffset = horizontal ? contentOffset.x : contentOffset.y
@@ -416,6 +429,19 @@ export default class extends Component {
416429
* @param {string} dir 'x' || 'y'
417430
*/
418431
updateIndex = (offset, dir, cb) => {
432+
// Android ScrollView will not scrollTo certain offset when props change
433+
const callback = () => {
434+
cb()
435+
if (Platform.OS === 'android') {
436+
this.state.index === 0 &&
437+
this.scrollView.scrollTo({ x: state.width, y: 0, animated: false })
438+
this.state.index === this.state.total - 1 &&
439+
this.scrollView.scrollTo({
440+
x: state.width * this.state.total,
441+
animated: false
442+
})
443+
}
444+
}
419445
const state = this.state
420446
let index = state.index
421447
if (!this.internals.offset)
@@ -462,14 +488,14 @@ export default class extends Component {
462488
newState.offset = { x: 0, y: 0 }
463489
newState.offset[dir] = offset[dir] + 1
464490
this.setState(newState, () => {
465-
this.setState({ offset: offset }, cb)
491+
this.setState({ offset: offset }, callback)
466492
})
467493
} else {
468494
newState.offset = offset
469-
this.setState(newState, cb)
495+
this.setState(newState, callback)
470496
}
471497
} else {
472-
this.setState(newState, cb)
498+
this.setState(newState, callback)
473499
}
474500
}
475501

@@ -488,12 +514,7 @@ export default class extends Component {
488514
if (state.dir === 'x') x = diff * state.width
489515
if (state.dir === 'y') y = diff * state.height
490516

491-
if (Platform.OS !== 'ios') {
492-
this.scrollView &&
493-
this.scrollView[animated ? 'setPage' : 'setPageWithoutAnimation'](diff)
494-
} else {
495-
this.scrollView && this.scrollView.scrollTo({ x, y, animated })
496-
}
517+
this.scrollView && this.scrollView.scrollTo({ x, y, animated })
497518

498519
// update scroll state
499520
this.internals.isScrolling = true
@@ -535,12 +556,7 @@ export default class extends Component {
535556
if (state.dir === 'x') x = diff * state.width
536557
if (state.dir === 'y') y = diff * state.height
537558

538-
if (Platform.OS !== 'ios') {
539-
this.scrollView &&
540-
this.scrollView[animated ? 'setPage' : 'setPageWithoutAnimation'](diff)
541-
} else {
542-
this.scrollView && this.scrollView.scrollTo({ x, y, animated })
543-
}
559+
this.scrollView && this.scrollView.scrollTo({ x, y, animated })
544560

545561
// update scroll state
546562
this.internals.isScrolling = true
@@ -655,11 +671,11 @@ export default class extends Component {
655671
}
656672

657673
renderTitle = () => {
658-
const child = this.props.children[this.state.index]
674+
const child = this.state.children[this.state.index]
659675
const title = child && child.props && child.props.title
660676
return title ? (
661677
<View style={styles.title}>
662-
{this.props.children[this.state.index].props.title}
678+
{this.state.children[this.state.index].props.title}
663679
</View>
664680
) : null
665681
}
@@ -689,13 +705,11 @@ export default class extends Component {
689705
}
690706

691707
return (
692-
<TouchableOpacity
708+
<TouchableOpacity
693709
onPress={() => button !== null && this.scrollBy(-1)}
694710
disabled={this.props.disablePrevButton}
695711
>
696-
<View>
697-
{button}
698-
</View>
712+
<View>{button}</View>
699713
</TouchableOpacity>
700714
)
701715
}
@@ -735,35 +749,20 @@ export default class extends Component {
735749
}
736750

737751
renderScrollView = pages => {
738-
if (Platform.OS === 'ios') {
739-
return (
740-
<ScrollView
741-
ref={this.refScrollView}
742-
{...this.props}
743-
{...this.scrollViewPropOverrides()}
744-
contentContainerStyle={[styles.wrapperIOS, this.props.style]}
745-
contentOffset={this.state.offset}
746-
onScrollBeginDrag={this.onScrollBegin}
747-
onMomentumScrollEnd={this.onScrollEnd}
748-
onScrollEndDrag={this.onScrollEndDrag}
749-
style={this.props.scrollViewStyle}
750-
>
751-
{pages}
752-
</ScrollView>
753-
)
754-
}
755752
return (
756-
<ViewPagerAndroid
753+
<ScrollView
757754
ref={this.refScrollView}
758755
{...this.props}
759-
initialPage={this.props.loop ? this.state.index + 1 : this.state.index}
760-
onPageScrollStateChanged={this.onPageScrollStateChanged}
761-
onPageSelected={this.onScrollEnd}
762-
key={pages.length}
763-
style={[styles.wrapperAndroid, this.props.style]}
756+
{...this.scrollViewPropOverrides()}
757+
contentContainerStyle={[styles.wrapperIOS, this.props.style]}
758+
contentOffset={this.state.offset}
759+
onScrollBeginDrag={this.onScrollBegin}
760+
onMomentumScrollEnd={this.onScrollEnd}
761+
onScrollEndDrag={this.onScrollEndDrag}
762+
style={this.props.scrollViewStyle}
764763
>
765764
{pages}
766-
</ViewPagerAndroid>
765+
</ScrollView>
767766
)
768767
}
769768

@@ -772,9 +771,8 @@ export default class extends Component {
772771
* @return {object} react-dom
773772
*/
774773
render() {
775-
const { index, total, width, height } = this.state
774+
const { index, total, width, height, children } = this.state
776775
const {
777-
children,
778776
containerStyle,
779777
loop,
780778
loadMinimal,

0 commit comments

Comments
 (0)