Skip to content

Commit

Permalink
[leecadegh-36] Use flex for resizing and get dimensions from onLayout
Browse files Browse the repository at this point in the history
  • Loading branch information
timmywil committed Jul 14, 2017
1 parent e20c175 commit e8173fe
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 40 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ import Swiper from 'react-native-swiper';
var styles = StyleSheet.create({
wrapper: {
},
content: {
},
slide1: {
flex: 1,
justifyContent: 'center',
Expand Down Expand Up @@ -149,7 +151,7 @@ var styles = StyleSheet.create({
var swiper = React.createClass({
render: function() {
return (
<Swiper style={styles.wrapper} showsButtons={true}>
<Swiper style={styles.wrapper} contentStyle={styles.content} showsButtons={true}>
<View style={styles.slide1}>
<Text style={styles.text}>Hello Swiper</Text>
</View>
Expand Down Expand Up @@ -185,7 +187,8 @@ AppRegistry.registerComponent('myproject', () => swiper);
| :------------ |:---------------:| :---------------:| :-----|
| width | - | `number` | If no specify default enable fullscreen mode by `flex: 1`. |
| height | - | `number` | If no specify default fullscreen mode by `flex: 1`. |
| style | {...} | `style` | See default style in source. |
| style | {...} | `style` | Customize the style of the View container. |
| contentStyle | {...} | `style` | Customize the style of the ScrollView that has the content. |
| loadMinimal | false | `bool` | Only load current index slide , `loadMinimalSize` slides before and after. |
| loadMinimalSize | 1 | `number` | see `loadMinimal` |
| loadMinimalLoader | `<ActivityIndicator />` | `element` | Custom loader to display when slides aren't loaded
Expand Down Expand Up @@ -225,7 +228,6 @@ AppRegistry.registerComponent('myproject', () => swiper);

| Prop | Default | Type | Description |
| :------------ |:---------------:| :---------------:| :-----|
| style | {...} | `style` | Custom styles will merge with the default styles. |
| title | {<Text numberOfLines={1}>...</Text>} | `element` | If this parameter is not specified, will not render the title. |

#### Basic props of `<ScrollView />`
Expand Down
71 changes: 34 additions & 37 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,28 @@
* react-native-swiper
* @author leecade<leecade@163.com>
*/
import React, { Component, ViewPropTypes } from 'react'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
Text,
View,
ViewPropTypes,
ScrollView,
Dimensions,
TouchableOpacity,
ViewPagerAndroid,
Platform,
ActivityIndicator
} from 'react-native'

const { width, height } = Dimensions.get('window')

/**
* Default styles
* @type {StyleSheetPropType}
*/
const styles = {
container: {
backgroundColor: 'transparent',
position: 'relative'
position: 'relative',
flex: 1
},

wrapper: {
Expand Down Expand Up @@ -102,6 +101,7 @@ export default class extends Component {
horizontal: PropTypes.bool,
children: PropTypes.node.isRequired,
style: ViewPropTypes.style,
contentStyle: ViewPropTypes.style,
pagingEnabled: PropTypes.bool,
showsHorizontalScrollIndicator: PropTypes.bool,
showsVerticalScrollIndicator: PropTypes.bool,
Expand Down Expand Up @@ -155,7 +155,7 @@ export default class extends Component {
* Init states
* @return {object} states
*/
state = this.initState(this.props, true)
state = this.initState(this.props)

/**
* autoplay timer
Expand All @@ -165,10 +165,8 @@ export default class extends Component {
loopJumpTimer = null

componentWillReceiveProps (nextProps) {
const sizeChanged = (nextProps.width || width) !== this.state.width ||
(nextProps.height || height) !== this.state.height
if (!nextProps.autoplay && this.autoplayTimer) clearTimeout(this.autoplayTimer)
this.setState(this.initState(nextProps, sizeChanged))
this.setState(this.initState(nextProps))
}

componentDidMount () {
Expand All @@ -180,9 +178,9 @@ export default class extends Component {
this.loopJumpTimer && clearTimeout(this.loopJumpTimer)
}

initState (props, setOffsetInState) {
initState (props) {
// set the current state
const state = this.state || {}
const state = this.state || { width: 0, height: 0, offset: { x: 0, y: 0 } }

const initState = {
autoplayEnd: false,
Expand All @@ -199,32 +197,11 @@ export default class extends Component {
// retain the index
initState.index = state.index
} else {
// reset the index
setOffsetInState = true // if the index is reset, go ahead and update the offset in state
initState.index = initState.total > 1 ? Math.min(props.index, initState.total - 1) : 0
}

// Default: horizontal
initState.dir = props.horizontal === false ? 'y' : 'x'
initState.width = props.width || width
initState.height = props.height || height
newInternals.offset = {}

if (initState.total > 1) {
let setup = initState.index
if (props.loop) {
setup++
}
newInternals.offset[initState.dir] = initState.dir === 'y'
? initState.height * setup
: initState.width * setup
}

// only update the offset in state if needed, updating offset while swiping
// causes some bad jumping / stuttering
if (setOffsetInState) {
initState.offset = newInternals.offset
}

this.internals = newInternals
return initState
Expand All @@ -235,6 +212,29 @@ export default class extends Component {
return Object.assign({}, this.state, this.internals)
}

setDimensions = (event) => {
const { width, height } = event.nativeEvent.layout
const offset = this.internals.offset = {}
const state = { width, height }

if (this.state.total > 1) {
let setup = this.state.index
if (this.props.loop) {
setup++
}
offset[this.state.dir] = this.state.dir === 'y'
? height * setup
: width * setup
}

// only update the offset in state if needed, updating offset while swiping
// causes some bad jumping / stuttering
if (width !== this.state.width || height !== this.state.height) {
state.offset = offset
}
this.setState(state)
}

loopJump = () => {
if (!this.state.loopJump) return
const i = this.state.index + (this.props.loop ? 1 : 0)
Expand Down Expand Up @@ -551,7 +551,7 @@ export default class extends Component {
<ScrollView ref='scrollView'
{...this.props}
{...this.scrollViewPropOverrides()}
contentContainerStyle={[styles.wrapper, this.props.style]}
contentContainerStyle={[styles.wrapper, this.props.contentStyle]}
contentOffset={this.state.offset}
onScrollBeginDrag={this.onScrollBegin}
onMomentumScrollEnd={this.onScrollEnd}
Expand Down Expand Up @@ -626,10 +626,7 @@ export default class extends Component {
}

return (
<View style={[styles.container, {
width: state.width,
height: state.height
}]}>
<View style={[styles.container, this.props.style]} onLayout={this.setDimensions}>
{this.renderScrollView(pages)}
{props.showsPagination && (props.renderPagination
? this.props.renderPagination(state.index, state.total, this)
Expand Down

4 comments on commit e8173fe

@SSTPIERRE2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timmywil Great work! Did this fix the orientation issue for you? I'm wondering if this will work out-of-the-box or if I might have to wire up some code to get landscape working. Thanks!

@timmywil
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SSTPIERRE2 It worked for me. I haven't tested any cases other than mine, tho.

@SSTPIERRE2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timmywil anything extra to setup when calling Swiper? Like setting up a componentWillReceiveProps and setting height and width or something. I'm testing on a fresh RN init'd app, with only a fresh swiper rendered.

@timmywil
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I removed that as it stopped working when I upgraded react-native. You shouldn't have to do anything, but let me know.

Please sign in to comment.