ReactNative基础(三)了解ScrollView并打造一个Banner效果

此博客基于react-native-0.48.4

ScrollView简介
  • 一个包装了平台的ScrollView(滚动视图)的组件,同时还集成了触摸锁定的“响应者”系统。
  • 这个就跟Android中的ScrollView总体来说是一样的,将会超出屏幕的视图使用ScrollView包裹来滑动查看。
  • ScrollView文档属性介绍
来编写个案例实现下

新创建个ScrollTest.js组件,然后在index.android.js中引入这个组件

index.android.js

var Scroll = require('./src/scrollTest');

export default class UseScrollView extends Component {
    render() {
        return (
            <View style={{flex: 1}}>
                <Scroll/>
            </View>
        );
    }
}

AppRegistry.registerComponent('UseScrollView', () => UseScrollView);
在组件中创建5个视图让内容超出屏幕,这样使用ScrollView就可以清楚的看到效果
//屏幕信息
var dimensions = require('Dimensions');
//获取屏幕的宽度和高度
var {width} = dimensions.get('window');

class ScrollTest extends Component {
    render() {
        return (
            <ScrollView>
                {this.getView()}
            </ScrollView>
        );
    }

    getView() {
        var all = [];
        var colors = ['red', 'blue', 'green', 'black', 'gray'];
        for (var i = 0; i < colors.length; i++) {
            //往数组添加元素
            all.push(
                //往数组添加元素一定要加一个唯一标识
                <View key={i} style={{
                    justifyContent: 'center',
                    alignItems: 'center',
                    backgroundColor: colors[i],
                    width: width,
                    height: 180
                }}>
                    <Text style={{color: 'white'}}>第{i + 1}个文本</Text>
                </View>
            );
        }
        //返回数据
        return all;
    }
}

module.exports = ScrollTest;

效果图:

这里写图片描述

使用呢也是超级的简单,将需要滑动的内容包裹即可。

了解ScrollView常用的一些属性
  • horizontal bool 当此属性为true的时候,所有的子视图会在水平方向上排成一行,而不是默认的在垂直方向上排成一列。默认值为false。
  • showsHorizontalScrollIndicator bool 当此属性为true的时候,显示一个水平方向的滚动条。
  • showsVerticalScrollIndicator bool 当此属性为true的时候,显示一个垂直方向的滚动条。
  • pagingEnabled bool 当值为true时,滚动条会停在滚动视图的尺寸的整数倍位置。这个可以用在水平分页上。默认值为false。
  • scrollEnabled bool 当值为false的时候,内容不能滚动,默认值为true。
  • onMomentumScrollEnd?: function 滚动动画结束时调用此函数。
  • 更多属性和方法介绍可以看这里ScrollView

将ScrollView设置为水平滚动,来查看下效果:

这里写图片描述

好了,基本使用也就这些了;接下来使用ScrollView实现一个自动轮播的Banner。

使用ScrollView打造一个轮播图,创建一个banner.js组建来码代码。

先来欣赏一下效果图这样才有看下去的动力,是吧!
这里写图片描述

第一步:定义好我们的图片资源,创建一个水平的ScrollView并循环往里面添加需要展示的图片
var banner = [
    'http://oweq6in8r.bkt.clouddn.com/about.jpg',
    'http://oweq6in8r.bkt.clouddn.com/liuliangqiu.jpg',
    'http://oweq6in8r.bkt.clouddn.com/rn.jpeg',
    'http://image.baidu.com/search/地址太长/%3D0.jpg'
];
//屏幕信息
var dimensions = require('Dimensions');
//获取屏幕的宽度和高度
var {width} = dimensions.get('window');

class Banner extends Component {

    render() {
        return (
            <View style={styles.container}>
                <ScrollView
                    horizontal={true}
                    showsHorizontalScrollIndicator={false}
                    pagingEnabled={true}>

                    {/*显示轮播图的图片内容*/}
                    {this.getImages()}
                </ScrollView>
            </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;
    }

}

const styles = StyleSheet.create({
    container: {
        marginTop: 8,
    },
    image: {
        width: width,
        height: 240,
    }
});

module.exports = Banner;
  • 一个可以横向滑动的Viewpager效果就出来了

  • 接下来就需要添加我们底部的页面指示器了,与添加图片方式一致for循环添加。
第二步:添加底部的页面指示器,在render()函数中添加代码就不贴出所有了,避免篇幅太长。
<ScrollView>
    ...
</ScrollView>
{/*生成底部的圆点指示器*/}
<View style={styles.indicator}>
    {this.getIndicators()}
</View>


//获取左下角的4个圆点
getIndicators() {
    var circles = [];
    for (var i = 0; i < banner.length; i++) {
        circles.push(
            <Text key={i}
                  style={styles.unselected}>&bull;</Text>//&bull; html转义字符圆点
        );
    }
    return circles;
}

//底部指示器的样式
indicator: {
    width: width,
    height: 40,
    position: 'absolute',
    bottom: 0,//放置在底部
    backgroundColor: 'rgba(0,0,0,0.5)',
    flexDirection: 'row',
    alignItems: 'center',
},
unselected: {
    marginLeft: 10,
    fontSize: 40,//也就是圆点的大小
    color: 'white'
}

底部指示器效果:

第三步:当我们左右滑动的时候我们需要来改变底部指示器圆点的颜色
  • 我们需要一个变量来保存当前滑动到了哪一个页面,我们可以定义一个var position
constructor(props) {
    super(props);
    this.state = {
        //当前显示的下标
        position: 0,
    }
}
  • 现在我们来修改ScrollView,添加一个页面滑动监听
<ScrollView
    //滚动动画结束时调用此函数。一帧滚动结束
    onMomentumScrollEnd={(v) => this.onAnimationEnd(v)}>
    ...
</ScrollView>

//v 则为scrollView对象
onAnimationEnd(v) {
    //1.求出水平方向的偏移量
    var offsetX = v.nativeEvent.contentOffset.x;
    //2.根据偏移量求出当前的页数  width为图片的宽度(banner的宽度 )
    var position = Math.round(offsetX / width);
    //3.更新状态机, 刷新圆点
    this.setState({
        position: position
    });
}
  • 通过监听函数,我们获取到了用户当前滑动到了哪一个页面;那么现在我们就需要动态修改指示器圆点对应的颜色。(如果没有阅读过这篇ReactNative基础(二)了解组件的生命周期,可以先看完再回过头来看这篇)
  • 现在我们只需要修改上面已经定义好的getIndicators()函数即可
//在循环创建圆点时判断添加的点是不是当前显示的页面,如果是的话则用选中的样式
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>
                  );
    }
    return circles;
}

selected: {
    marginLeft: 10,
    fontSize: 40,
    color: '#5CB85C'
},

欣赏下成果:

到这里基本上一个可以手动滑动的ViewPager效果就做好了是不是very exciting,为了让我们的ViewPager更加高大上我们添加个定时器,让它自动轮播。
  • 我们先来定义轮播的间隔时间
static defaultProps = {
    //间隔时间 1000ms
    duration: 1000
};
  • 当组件完全渲染完成之后,开启我们的定时器
//绘制完成,开启定时器
componentDidMount() {
    this.startTimer();
}
//开启定时器,并每隔1sposition从0~3循环
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);
}

var scrollView = this.refs.scrollView;这行代码就有点类似Android中的findViewById()来获取视图中的某个View,所以我们需要在ScrollView中添加一个属性,如下:

<ScrollView
    ref="scrollView">
    //...
</ScrollView>
  • 最最最后一步,当我们手动滑动轮播图的时候需要取消掉计时器、滑动结束之后恢复循环。
<ScrollView
    ref="scrollView"
    //手指按下的时候,停止计时器
    onTouchStart={() => clearInterval(this.timer)}>
</ScrollView>

手指抬起的时候也就是,我们滑动一页完毕之后的事件;也就是我们上面使用到的一个函数onAnimationEnd()那么我们只需要在函数的末尾继续调用我们的开启计时器函数即可。

onAnimationEnd(v) {
    //...
    this.startTimer();
}
好了一个美妙的轮播图效果就完成了;不负春光,野蛮生长。
源码下载地址
推荐阅读:
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code-Porter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值