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( ) } else { touchArr.push() } } return ( {Children.map(this.props.children, (child, index) => ( this.props.imgTouch(e)} activeOpacity={this.props.activeOpacity} width={this.props.width} /> ))} {this.props.progressBar ? ( {touchArr} ) : null} ) } }