123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- import React, { Children } from 'react'
- import {
- TouchableOpacity,
- View,
- Dimensions,
- Animated,
- Easing,
- PanResponder,
- } from 'react-native'
- import PropTypes from 'prop-types'
- import CarouselItem from './carouselItem'
- export default class CarouselHorizontal extends React.Component {
- constructor(props) {
- super(props)
- this.state = {
- translateX: new Animated.Value(0),
- fresh: true,
- }
- this.index = 0
- this.scrollOffset = {
- startX: 0,
- endX: 0,
- directionX: 'R',
- }
- this.panResponder = props.enableScroll
- ? PanResponder.create({
- onStartShouldSetPanResponder: (evt, gestureState) => {},
- onStartShouldSetPanResponderCapture: (evt, gestureState) => {
- this.props.hasTouch && this.props.hasTouch(true)
- },
- onMoveShouldSetResponderCapture: () => true,
- onMoveShouldSetPanResponder: (evt, gestureState) => true,
- onMoveShouldSetPanResponderCapture: () => true,
- onPanResponderGrant: (evt, gestureState) => {
- //
- // if (this.props.panResponBool) {
- // this.props.hasTouch && this.props.hasTouch(true);
- // }
- this.scrollOffset.startX = evt.nativeEvent.pageX
- },
- onPanResponderRelease: (evt, gestureState) => {
- this.scrollOffset.endX = evt.nativeEvent.pageX
- this.directionJudg()
- this.index =
- this.scrollOffset.directionX == 'R' ? this.index - 2 : this.index
- if (this.index <= -2) {
- this.index = 0
- } else {
- this.scrollCarousel(this.props.children.length)
- }
- //
- // if (this.props.panResponBool) {
- // this.props.hasTouch && this.props.hasTouch(false);
- // }
- },
- onShouldBlockNativeResponder: (evt, gestureState) => {
- this.props.hasTouch && this.props.hasTouch(false)
- // 返回一个布尔值,决定当前组件是否应该阻止原生组件成为JS响应者
- // 默认返回true。目前暂时只支持android。
- return true
- },
- })
- : {
- panHandlers: {},
- }
- }
- static propTypes = {
- width: PropTypes.number,
- imgTouch: PropTypes.func,
- activeOpacity: PropTypes.number,
- enableScroll: PropTypes.bool,
- delayTime: PropTypes.number,
- duration: PropTypes.number,
- tintColor: PropTypes.string,
- progressBar: PropTypes.bool,
- panResponBool: PropTypes.bool,
- }
- static defaultProps = {
- width: Dimensions.get('window').width,
- activeOpacity: 1,
- imgTouch: () => {},
- enableScroll: false,
- delayTime: 5000,
- duration: 300,
- tintColor: 'red',
- progressBar: true,
- panResponBool: false,
- touchArrStyle: {
- bottom: '20%',
- flexDirection: 'row',
- },
- entertouchItemStyle: {
- marginRight: 5,
- width: 20,
- height: 5,
- borderRadius: 5,
- },
- touchItemStyle: {
- backgroundColor: '#FFF',
- opacity: 0.5,
- marginRight: 5,
- width: 5,
- height: 5,
- borderRadius: 5,
- },
- }
- componentDidMount() {
- this.scrollTimer = setInterval(
- () => this.scrollCarousel(this.props.children.length),
- this.props.delayTime
- )
- }
- //组件将被卸载
- componentWillUnmount() {
- //重写组件的setState方法,直接返回空
- this.setState = (state, callback) => {
- return
- }
- }
- directionJudg() {
- this.scrollOffset.directionX =
- this.scrollOffset.endX - this.scrollOffset.startX > 0 ? 'R' : 'L'
- }
- scrollCarousel(count, stopTimer) {
- let styleWidth = -this.props.width
- this.index++
- if (this._animated) {
- this._animated.stop()
- }
- this._animated = Animated.timing(this.state.translateX, {
- toValue: styleWidth * this.index,
- duration: this.props.duration,
- Easing: Easing.linear,
- }).start(() => {
- if (this.index >= count) {
- this.index = 0
- this.state.translateX.setValue(0)
- }
- this.setState({ fresh: !this.state.fresh })
- })
- }
- render() {
- let touchArr = []
- for (let i = 0; i < this.props.children.length; i++) {
- if (this.index == i) {
- touchArr.push(
- <View
- key={i}
- style={[
- this.props.entertouchItemStyle,
- { backgroundColor: this.props.tintColor },
- ]}
- />
- )
- } else {
- touchArr.push(<View key={i} style={[this.props.touchItemStyle]} />)
- }
- }
- return (
- <View
- style={{
- // width: this.props.width * this.props.children.length,
- flex: 1,
- }}
- >
- <Animated.View
- {...this.panResponder.panHandlers}
- style={[
- {
- width: this.props.width * this.props.children.length,
- overflow: 'hidden',
- flexDirection: 'row',
- justifyContent: 'flex-start',
- },
- {
- transform: [
- {
- translateX: this.state.translateX,
- },
- ],
- },
- ]}
- >
- {Children.map(this.props.children, (child, index) => (
- <CarouselItem
- item={child}
- index={index}
- imgTouch={e => this.props.imgTouch(e)}
- activeOpacity={this.props.activeOpacity}
- width={this.props.width}
- />
- ))}
- </Animated.View>
- {this.props.progressBar ? (
- <View
- style={[
- {
- alignSelf: 'center',
- },
- this.props.touchArrStyle,
- ]}
- >
- {touchArr}
- </View>
- ) : null}
- </View>
- )
- }
- }
|