美文网首页React Native开发
react-native scrollView实现 banner

react-native scrollView实现 banner

作者: 182058734bf0 | 来源:发表于2021-09-27 20:37 被阅读0次

    复制就可以使用纯ts

    import React, {Component} from "react";
    import {Image, ScrollView, Text, View, Dimensions} from "react-native";
    const {width, height} = Dimensions.get('window');
    export interface BannerPropTypes {
        imageList: Array<string>,
        onChangeIndex:(num: number) => void;
        duration:number,
    }
    
    export default class Banner extends Component<BannerPropTypes> {
        private scrollView: any;
        private itemWidth: number = width;
        private itemHeight: number = width * 9 / 16;
        private page = 1;
        private pageSize = 5;
        private timer: any;
        state = {
            bannerList: [],
            offSetX:0,
            snapToOffsets:[]
        }
        constructor(props: BannerPropTypes) {
            super(props);
    
        }
        componentDidMount() {
            this._setInfiniteInterval()
            let bannerList = this.props.imageList
            bannerList.unshift(bannerList[bannerList.length - 1])
            bannerList.push(bannerList[1])
            this.pageSize = bannerList.length;
            const snapToOffsets: Array<number> = []
            for (let i = 0; i < bannerList.length; i++) {
                snapToOffsets.push((i) * (this.itemWidth))
            }
            this.setState({
                snapToOffsets,
                bannerList
            })
        }
        componentWillUnmount() {
            this._stopInfiniteInterval()
        }
        render() {
            return <ScrollView
                ref={scrollView => this.scrollView = scrollView}
                contentOffset={{x: this.state.offSetX, y: 0}}
                scrollEnabled={true}
                horizontal={true}
                snapToOffsets={this.state.snapToOffsets}
                showsHorizontalScrollIndicator={false}
                onScrollBeginDrag={this._stopInfiniteInterval}
                onScrollEndDrag={this._setInfiniteInterval}
                decelerationRate="fast"
                onMomentumScrollEnd={(e) => {//手动拖拽后响应
                    if (e.nativeEvent.contentOffset.x > 0) {
                        this.page = Math.round(e.nativeEvent.contentOffset.x / this.itemWidth)
                        if (this.page >= this.pageSize - 1) {
                            this.page = 1;
                            this.setState({page: this.page, offSetX: this.page * this.itemWidth})
                            this._callback(this.page)
                            this.scrollView.scrollTo({
                                x: this.page * this.itemWidth,
                                animated: false,
                            })
                        } else {
                            this.setState({page: this.page})
                            this._callback(this.page)
                        }
                    } else {
                        this.page = this.pageSize - 2
                        this.setState({page: this.page, offSetX: this.page * this.itemWidth})
                        this._callback(this.page)
                        this.scrollView.scrollTo({
                            x: this.page * this.itemWidth,
                            animated: false,
                        })
                    }
                }}
                keyboardShouldPersistTaps={'handled'}>
                {this.state.bannerList.map((imgUri, index) => {
                    return <Image key={"banner"+index} resizeMode={"stretch"} source={{uri: imgUri}} style={{width: this.itemWidth, height: this.itemHeight,}}/>
                })}
            </ScrollView>
        }
    
        //设置轮播的定时器
        _setInfiniteInterval = () => {
            this.timer = setInterval(() => {
                this.page++;
                this.scrollView.scrollTo({
                    x: this.page * this.itemWidth,
                    animated: true,
                })
                this.setState({page: this.page})
                if (this.page === this.pageSize - 1) {
                    this.page = 1;
                    setTimeout(() => {
                        this.setState({
                            offSetX: this.page * this.itemWidth,
                        })
                        this.scrollView.scrollTo({
                            x: this.page * this.itemWidth,
                            animated: false,
                        })
                    }, 300)
                    this._callback(this.page)
                }else {
                    this._callback(this.page)
                }
            }, this.props.duration)
        };
        //清除轮播定时器
        _stopInfiniteInterval = () => {
            this.timer && clearInterval(this.timer);
        };
    
        _callback=(page:number)=>{
            const {onChangeIndex}=this.props
            onChangeIndex(page-1);
        }
    }
    
    
    

    使用

    
               <Banner
                                    onChangeIndex={index=>this.textComplete(index)}
                                    duration={5000}
                                    imageList={images} />
    

    效果

    image.png

    diy

    image.png

    相关文章

      网友评论

        本文标题:react-native scrollView实现 banner

        本文链接:https://www.haomeiwen.com/subject/qneknltx.html