mirror of
https://github.com/zhigang1992/react-native-swiper.git
synced 2026-04-29 04:35:47 +08:00
fixes #7 inject state in ScrollResponders @thanks smothers
Now you can get `state` and `context`(ref to swiper's `this`) from params
This commit is contained in:
52
README.md
52
README.md
@@ -35,6 +35,8 @@ The best Swiper component for React Native.
|
||||
|
||||
- [x] Custom pagination style
|
||||
|
||||
- [x] State inject
|
||||
|
||||
## Changelogs
|
||||
|
||||
- **[v1.2.2]**
|
||||
@@ -167,7 +169,7 @@ AppRegistry.registerComponent('swiper', () => swiper)
|
||||
|
||||
#### Basic
|
||||
|
||||
| Prop | Default | Type | Describe |
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| horizontal | true | `bool` | If `true`, the scroll view's children are arranged horizontally in a row instead of vertically in a column. |
|
||||
| loop | true | `bool` | Set to `true` to enable continuous loop mode. |
|
||||
@@ -177,7 +179,7 @@ AppRegistry.registerComponent('swiper', () => swiper)
|
||||
|
||||
#### Custom basic style & content
|
||||
|
||||
| Prop | Default | Type | Describe |
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| width | - | `number` | If no specify default enable fullscreen mode by `flex: 1`. |
|
||||
| height | - | `number` | If no specify default fullscreen mode by `flex: 1`. |
|
||||
@@ -185,17 +187,17 @@ AppRegistry.registerComponent('swiper', () => swiper)
|
||||
|
||||
#### Pagination
|
||||
|
||||
| Prop | Default | Type | Describe |
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| showsPagination | true | `bool` | Set to `true` make pagination visible. |
|
||||
| paginationStyle | {...} | `style` | Custom styles will merge with the default styles. |
|
||||
| renderPagination | - | `function` | Complete control how to render pagination with two params (`index`, `total`) ref to `this.state.index` / `this.state.total`, For example: show numbers instead of dots. |
|
||||
| renderPagination | - | `function` | Complete control how to render pagination with three params (`index`, `total`, `context`) ref to `this.state.index` / `this.state.total` / `this`, For example: show numbers instead of dots. |
|
||||
| dot | `<View style={{backgroundColor:'rgba(0,0,0,.2)', width: 8, height: 8,borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />` | `element` | Allow custom the dot element. |
|
||||
| activeDot | `<View style={{backgroundColor: '#007aff', width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />` | `element` | Allow custom the active-dot element. |
|
||||
|
||||
#### Autoplay
|
||||
|
||||
| Prop | Default | Type | Describe |
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| autoplay | true | `bool` | Set to `true` enable auto play mode. |
|
||||
| autoplayTimeout | 2.5 | `number` | Delay between auto play transitions (in second). |
|
||||
@@ -203,7 +205,7 @@ AppRegistry.registerComponent('swiper', () => swiper)
|
||||
|
||||
#### Control buttons
|
||||
|
||||
| Prop | Default | Type | Describe |
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| showsButtons | true | `bool` | Set to `true` make control buttons visible. |
|
||||
| buttonWrapperStyle | `{backgroundColor: 'transparent', flexDirection: 'row', position: 'absolute', top: 0, left: 0, flex: 1, paddingHorizontal: 10, paddingVertical: 10, justifyContent: 'space-between', alignItems: 'center'}` | `style` | Custom styles. |
|
||||
@@ -212,14 +214,14 @@ AppRegistry.registerComponent('swiper', () => swiper)
|
||||
|
||||
#### Props of Children
|
||||
|
||||
| Prop | Default | Type | Describe |
|
||||
| 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 />`
|
||||
|
||||
| Prop | Default | Type | Describe |
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| horizontal | true | `bool` | If `true`, the scroll view's children are arranged horizontally in a row instead of vertically in a column. |
|
||||
| pagingEnabled | true | `bool` | If true, the scroll view stops on multiples of the scroll view's size when scrolling. This can be used for horizontal pagination. |
|
||||
@@ -234,16 +236,34 @@ AppRegistry.registerComponent('swiper', () => swiper)
|
||||
|
||||
#### Supported ScrollResponder
|
||||
|
||||
| Prop | Default | Type | Describe |
|
||||
| Prop | Params | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| onMomentumScrollBegin | - | `function` | When animation begins after letting up |
|
||||
| onMomentumScrollEnd | - | `function` | Makes no sense why this occurs first during bounce |
|
||||
| onTouchStartCapture | - | `function` | Immediately after `onMomentumScrollEnd` |
|
||||
| onTouchStart | - | `function` | Same, but bubble phase |
|
||||
| onTouchEnd | - | `function` | You could hold the touch start for a long time |
|
||||
| onResponderRelease | - | `function` | When lifting up - you could pause forever before * lifting |
|
||||
| onMomentumScrollBegin | `e` / `state` / `context` | `function` | When animation begins after letting up |
|
||||
| onMomentumScrollEnd | `e` / `state` / `context` | `function` | Makes no sense why this occurs first during bounce |
|
||||
| onTouchStartCapture | `e` / `state` / `context` | `function` | Immediately after `onMomentumScrollEnd` |
|
||||
| onTouchStart | `e` / `state` / `context` | `function` | Same, but bubble phase |
|
||||
| onTouchEnd | `e` / `state` / `context` | `function` | You could hold the touch start for a long time |
|
||||
| onResponderRelease | `e` / `state` / `context` | `function` | When lifting up - you could pause forever before * lifting |
|
||||
|
||||
> @see: https://github.com/facebook/react-native/blob/master/Libraries/Components/ScrollResponder.js
|
||||
> Note: each ScrollResponder be injected with two params: `state` and `context`, you can get `state` and `this`(ref to swiper's context) from params, for example:
|
||||
|
||||
```jsx
|
||||
var swiper = React.createClass({
|
||||
_onMomentumScrollEnd: function (e, state, context) {
|
||||
console.log(state, context.state)
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<Swiper style={styles.wrapper}
|
||||
onMomentumScrollEnd ={this._onMomentumScrollEnd}
|
||||
...
|
||||
</Swiper>
|
||||
)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
> More ScrollResponder info, see: https://github.com/facebook/react-native/blob/master/Libraries/Components/ScrollResponder.js
|
||||
|
||||
### Examples
|
||||
|
||||
|
||||
41
dist/index.js
vendored
41
dist/index.js
vendored
@@ -192,6 +192,10 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
*/
|
||||
autoplayTimer: null,
|
||||
|
||||
componentWillMount: function componentWillMount() {
|
||||
this.props = this.injectState(this.props);
|
||||
},
|
||||
|
||||
componentDidMount: function componentDidMount() {
|
||||
this.autoplay();
|
||||
},
|
||||
@@ -227,7 +231,7 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
});
|
||||
|
||||
this.setTimeout(function () {
|
||||
_this2.props.onScrollBeginDrag && _this2.props.onScrollBeginDrag.call(_this2, e);
|
||||
_this2.props.onScrollBeginDrag && _this2.props.onScrollBeginDrag(e, _this2.state, _this2);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -251,7 +255,7 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
_this3.autoplay();
|
||||
|
||||
// if `onMomentumScrollEnd` registered will be called here
|
||||
_this3.props.onMomentumScrollEnd && _this3.props.onMomentumScrollEnd.call(_this3, e);
|
||||
_this3.props.onMomentumScrollEnd && _this3.props.onMomentumScrollEnd(e, _this3.state, _this3);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -400,6 +404,37 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Inject state to ScrollResponder
|
||||
* @param {object} props origin props
|
||||
* @return {object} props injected props
|
||||
*/
|
||||
injectState: function injectState(props) {
|
||||
var _this5 = this;
|
||||
|
||||
/* const scrollResponders = [
|
||||
'onMomentumScrollBegin',
|
||||
'onTouchStartCapture',
|
||||
'onTouchStart',
|
||||
'onTouchEnd',
|
||||
'onResponderRelease',
|
||||
]*/
|
||||
|
||||
for (var prop in props) {
|
||||
// if(~scrollResponders.indexOf(prop)
|
||||
if (typeof props[prop] === 'function' && prop !== 'onMomentumScrollEnd' && prop !== 'renderPagination' && prop !== 'onScrollBeginDrag') {
|
||||
(function () {
|
||||
var originResponder = props[prop];
|
||||
props[prop] = function (e) {
|
||||
return originResponder(e, _this5.state, _this5);
|
||||
};
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
return props;
|
||||
},
|
||||
|
||||
/**
|
||||
* Default render
|
||||
* @return {object} react-dom
|
||||
@@ -456,7 +491,7 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
onMomentumScrollEnd: this.onScrollEnd }),
|
||||
pages
|
||||
),
|
||||
props.showsPagination && (props.renderPagination ? this.props.renderPagination.call(this, state.index, state.total) : this.renderPagination()),
|
||||
props.showsPagination && (props.renderPagination ? this.props.renderPagination(state.index, state.total, this) : this.renderPagination()),
|
||||
this.renderTitle(),
|
||||
this.props.showsButtons && this.renderButtons()
|
||||
);
|
||||
|
||||
@@ -35,9 +35,15 @@ var styles = StyleSheet.create({
|
||||
})
|
||||
|
||||
var swiper = React.createClass({
|
||||
_onMomentumScrollEnd: function (e, state, context) {
|
||||
// you can get `state` and `this`(ref to swiper's context) from params
|
||||
console.log(state, context.state)
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<Swiper style={styles.wrapper} showsButtons={true}>
|
||||
<Swiper style={styles.wrapper}
|
||||
onMomentumScrollEnd={this._onMomentumScrollEnd}
|
||||
showsButtons={true}>
|
||||
<View style={styles.slide1}>
|
||||
<Text style={styles.text}>Hello Swiper</Text>
|
||||
</View>
|
||||
|
||||
@@ -192,6 +192,10 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
*/
|
||||
autoplayTimer: null,
|
||||
|
||||
componentWillMount: function componentWillMount() {
|
||||
this.props = this.injectState(this.props);
|
||||
},
|
||||
|
||||
componentDidMount: function componentDidMount() {
|
||||
this.autoplay();
|
||||
},
|
||||
@@ -227,7 +231,7 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
});
|
||||
|
||||
this.setTimeout(function () {
|
||||
_this2.props.onScrollBeginDrag && _this2.props.onScrollBeginDrag.call(_this2, e);
|
||||
_this2.props.onScrollBeginDrag && _this2.props.onScrollBeginDrag(e, _this2.state, _this2);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -251,7 +255,7 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
_this3.autoplay();
|
||||
|
||||
// if `onMomentumScrollEnd` registered will be called here
|
||||
_this3.props.onMomentumScrollEnd && _this3.props.onMomentumScrollEnd.call(_this3, e);
|
||||
_this3.props.onMomentumScrollEnd && _this3.props.onMomentumScrollEnd(e, _this3.state, _this3);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -400,6 +404,37 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Inject state to ScrollResponder
|
||||
* @param {object} props origin props
|
||||
* @return {object} props injected props
|
||||
*/
|
||||
injectState: function injectState(props) {
|
||||
var _this5 = this;
|
||||
|
||||
/* const scrollResponders = [
|
||||
'onMomentumScrollBegin',
|
||||
'onTouchStartCapture',
|
||||
'onTouchStart',
|
||||
'onTouchEnd',
|
||||
'onResponderRelease',
|
||||
]*/
|
||||
|
||||
for (var prop in props) {
|
||||
// if(~scrollResponders.indexOf(prop)
|
||||
if (typeof props[prop] === 'function' && prop !== 'onMomentumScrollEnd' && prop !== 'renderPagination' && prop !== 'onScrollBeginDrag') {
|
||||
(function () {
|
||||
var originResponder = props[prop];
|
||||
props[prop] = function (e) {
|
||||
return originResponder(e, _this5.state, _this5);
|
||||
};
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
return props;
|
||||
},
|
||||
|
||||
/**
|
||||
* Default render
|
||||
* @return {object} react-dom
|
||||
@@ -456,7 +491,7 @@ exports['default'] = _React$StyleSheet$Text$View$ScrollView$TouchableOpacity2['d
|
||||
onMomentumScrollEnd: this.onScrollEnd }),
|
||||
pages
|
||||
),
|
||||
props.showsPagination && (props.renderPagination ? this.props.renderPagination.call(this, state.index, state.total) : this.renderPagination()),
|
||||
props.showsPagination && (props.renderPagination ? this.props.renderPagination(state.index, state.total, this) : this.renderPagination()),
|
||||
this.renderTitle(),
|
||||
this.props.showsButtons && this.renderButtons()
|
||||
);
|
||||
|
||||
@@ -60,7 +60,7 @@ var swiper = React.createClass({
|
||||
</Swiper>
|
||||
|
||||
<Swiper style={styles.wrapper} height={240}
|
||||
onMomentumScrollEnd={function(){console.log('this.state.index:', this.state.index)}}
|
||||
onMomentumScrollEnd={function(e, state, context){console.log('index:', state.index)}}
|
||||
dot={<View style={{backgroundColor:'rgba(0,0,0,.2)', width: 5, height: 5,borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />}
|
||||
activeDot={<View style={{backgroundColor: '#000', width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />}
|
||||
paginationStyle={{
|
||||
|
||||
@@ -25,7 +25,7 @@ var styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
var renderPagination = function (index, total) {
|
||||
var renderPagination = function (index, total, context) {
|
||||
return (
|
||||
<View style={{
|
||||
position: 'absolute',
|
||||
|
||||
39
src/index.js
39
src/index.js
@@ -192,6 +192,10 @@ export default React.createClass({
|
||||
*/
|
||||
autoplayTimer: null,
|
||||
|
||||
componentWillMount() {
|
||||
this.props = this.injectState(this.props)
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
this.autoplay()
|
||||
},
|
||||
@@ -227,7 +231,7 @@ export default React.createClass({
|
||||
})
|
||||
|
||||
this.setTimeout(() => {
|
||||
this.props.onScrollBeginDrag && this.props.onScrollBeginDrag.call(this, e)
|
||||
this.props.onScrollBeginDrag && this.props.onScrollBeginDrag(e, this.state, this)
|
||||
})
|
||||
},
|
||||
|
||||
@@ -250,7 +254,7 @@ export default React.createClass({
|
||||
this.autoplay()
|
||||
|
||||
// if `onMomentumScrollEnd` registered will be called here
|
||||
this.props.onMomentumScrollEnd && this.props.onMomentumScrollEnd.call(this, e)
|
||||
this.props.onMomentumScrollEnd && this.props.onMomentumScrollEnd(e, this.state, this)
|
||||
})
|
||||
},
|
||||
|
||||
@@ -387,6 +391,35 @@ export default React.createClass({
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Inject state to ScrollResponder
|
||||
* @param {object} props origin props
|
||||
* @return {object} props injected props
|
||||
*/
|
||||
injectState(props) {
|
||||
/* const scrollResponders = [
|
||||
'onMomentumScrollBegin',
|
||||
'onTouchStartCapture',
|
||||
'onTouchStart',
|
||||
'onTouchEnd',
|
||||
'onResponderRelease',
|
||||
]*/
|
||||
|
||||
for(let prop in props) {
|
||||
// if(~scrollResponders.indexOf(prop)
|
||||
if(typeof props[prop] === 'function'
|
||||
&& prop !== 'onMomentumScrollEnd'
|
||||
&& prop !== 'renderPagination'
|
||||
&& prop !== 'onScrollBeginDrag'
|
||||
) {
|
||||
let originResponder = props[prop]
|
||||
props[prop] = (e) => originResponder(e, this.state, this)
|
||||
}
|
||||
}
|
||||
|
||||
return props
|
||||
},
|
||||
|
||||
/**
|
||||
* Default render
|
||||
* @return {object} react-dom
|
||||
@@ -434,7 +467,7 @@ export default React.createClass({
|
||||
{pages}
|
||||
</ScrollView>
|
||||
{props.showsPagination && (props.renderPagination
|
||||
? this.props.renderPagination.call(this, state.index, state.total)
|
||||
? this.props.renderPagination(state.index, state.total, this)
|
||||
: this.renderPagination())}
|
||||
{this.renderTitle()}
|
||||
{this.props.showsButtons && this.renderButtons()}
|
||||
|
||||
Reference in New Issue
Block a user