zoukankan      html  css  js  c++  java
  • [RN] React Native 幻灯片效果 Banner

    [RN] React Native 幻灯片效果 Banner

    1、定义Banner

    import React, {Component} from 'react';
    import {Image, ScrollView, StyleSheet, Text, View,} from 'react-native';
    
    var banner = [
        "http://a.hiphotos.baidu.com/image/pic/item/ac4bd11373f08202e2518d6d45fbfbedaa641ba4.jpg",
        "http://e.hiphotos.baidu.com/image/pic/item/0df3d7ca7bcb0a467e97177b6563f6246b60af3f.jpg",
        "http://g.hiphotos.baidu.com/image/pic/item/b8014a90f603738d87dff378bd1bb051f919ecd7.jpg",
        "http://b.hiphotos.baidu.com/image/pic/item/58ee3d6d55fbb2fb12adba45414a20a44723dce7.jpg",
    ];
    //屏幕信息
    var dimensions = require('Dimensions');
    //获取屏幕的宽度和高度
    var {width} = dimensions.get('window');
    
    class Banner extends Component {
    
        static defaultProps = {
            //定时器的间隔时间
            duration: 1000
    
        };
    
        constructor(props) {
            super(props);
            this.state = {
                //当前显示的下标
                position: 0,
            }
        }
    
        //绘制完成,开启定时器
        componentDidMount() {
            this.startTimer();
        }
    
        startTimer() {
            //1.拿到ScrollView
            var scrollView = this.refs.scrollView;
            this.timer = setInterval(() => {
                //设置圆点的下标
                var curr = this.state.position;
                if (curr + 1 > banner.length - 1) {
                    curr = 0;
                } else {
                    curr++;
                }
                //更新状态机,更新当前下标
                this.setState({
                    position: curr,
                });
                //滚动ScrollView,1.求出水平方向的平移量  offsetX = curr * width
                scrollView.scrollTo({x: curr * width, y: 0, animated: true})
            }, this.props.duration);
    
        }
    
        render() {
            return (
                <View style={styles.container}>
                    <ScrollView
                        ref="scrollView"
                        horizontal={true}
                        showsHorizontalScrollIndicator={false}
                        pagingEnabled={true}//自动分页
                        //滚动动画结束时调用此函数。一帧滚动结束
                        onMomentumScrollEnd={(v) => this.onAnimationEnd(v)}
                        //手指按下的时候,停止计时器
                        onTouchStart={() => clearInterval(this.timer)}>
    
                        {/*显示轮播图的图片内容*/}
                        {this.getImages()}
                    </ScrollView>
                    {/*生成底部的圆点指示器*/}
                    <View style={styles.indicator}>
                        {this.getIndicators()}
                    </View>
                </View>
    
            );
        }
    
        //获取轮播图显示的图片
        getImages() {
            var images = [];
            for (var i = 0; i < banner.length; i++) {
                images.push(
                    <View key={i}>
                        {<Image source={{uri: banner[i]}} style={styles.image}/>}
                    </View>
                );
            }
            return images;
        }
    
        //获取左下角的4个圆点
        getIndicators() {
            var circles = [];
            for (var i = 0; i < banner.length; i++) {
                circles.push(
                    <Text key={i}
                          style={i === this.state.position ? styles.selected : styles.unselected}>&bull;</Text>//&bull; html转义字符
                );
            }
            return circles;
        }
    
        //重写这个函数,系统已有的函数
        onAnimationEnd(v) {
            //1.求出水平方向的偏移量
            var offsetX = v.nativeEvent.contentOffset.x;
            //2.根据偏移量求出当前的页数  width为图片的宽度(banner的宽度 )
            var position = Math.round(offsetX / width);
            //3.更新状态机, 刷新圆点
            this.setState({
                position: position
            });
            this.startTimer();
        }
    
        //结束计时器
        componentWillUnmount(nextProps, nextState) {
            clearInterval(this.timer);
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            marginTop: 8,
        },
        //底部指示器的样式
        indicator: {
             width,
            height: 40,
            position: 'absolute',
            bottom: 0,
            backgroundColor: 'rgba(0,0,0,0.5)',
            flexDirection: 'row',
            justifyContent:"center",
            alignItems: 'center',
        },
        image: {
             width,
            height: 240,
        },
        selected: {
            marginLeft: 10,
            fontSize: 40,
            color: '#5CB85C'
        },
        unselected: {
            marginLeft: 10,
            fontSize: 40,
            color: 'white'
        }
    });
    
    module.exports = Banner;

    2、调用App.js

    import React, {Component} from 'react';
    import {Text, View} from 'react-native';
    
    var Banner = require('./Banner');
    
    export default class App extends Component<Props> {
        render() {
            return (
                <View style={{flex: 1}}>
                    <Banner/>
                    {/*占满屏幕剩余空间  父View必须设置 flex的值(充满屏幕)*/}
                    <View style={{
                        justifyContent: 'center',
                        alignItems: 'center',
                        flex: 1,
                    }}>
                        <Text>
                            我是一个会自动轮播的Banner
                        </Text>
                    </View>
                </View>
            );
        }
    }

    本博客地址: wukong1688

    本文原文地址:https://www.cnblogs.com/wukong1688/p/10817577.html

    转载请注明出处!谢谢~~

  • 相关阅读:
    Start Developing iOS Apps (Swift) 开始开发iOS应用(Swift)
    ansible copy file
    多个sshkey 指定key来clone仓库
    elastic search 日期为string类型导致视图无法展示时间的解决办法
    ubuntu 安装php 报错解决
    ruby hash 默认值的问题
    11.Mysql 之MHA(高可用)
    10. 主从复制-主从复制(基于GTID)--附加半同步复制
    9 .mysql的备份与恢复
    11.Mysql之回表、最左匹配、索引下推
  • 原文地址:https://www.cnblogs.com/wukong1688/p/10817577.html
Copyright © 2011-2022 走看看