• React Native scrollview 循环播放


     

     

     

     


     
     
     
     
    react-native-swiper 解析
     
    1.传递组件给swiper,作为swiper组件的children,
    2.假如 有 4 张图片需要循环播放,那么传给swiper 4个 <Image /> (1、2、3、4)
       事实上swiper组件内会对其进行一次编辑 : 4、1、2、3、4、1
    3.依次正序、横向滑动,滑到4,然后滑到1,此时scrollview会马上更新contentOffSet(x: y:)
    即滑到 1 的时候回马上更新 contentOffSetX 到 第一个1位置。 倒序滑动逻辑如同正序
     
     
    另一种实现方案(OC上使用一切正常)
    1.scrollview上放3个<Image />组件,默认显示中间的Image组件, 左右滑动到两边的边界x坐标(0,2*screenWidth)
    马上更新contentOffSetX到 screenWidth(即还是中间的Image组件)同时更新图片
    2.RN实现会有闪屏现象,因为渲染一个图片较慢,尤其是大图。
    3.这种方式实现起来并不合适
     
     
     
    模仿swiper简单实现循环播放scrollview
    'use strict'
     
    import React, { Component, PropTypes } from 'React'
    import {
        AppRegistry,
        StyleSheet,
        View,
        ScrollView,
        Text
     
    } from 'react-native'
     
    export default class ImageLoopPlayer extends Component {
     
        constructor(props) {
            super(props)
     
            let total  = props.children ? props.children.length || 1 : 0
            let offSetX = props.children.length > props.defaultIndex ?
    (props.defaultIndex + 1) * props.componentWidth : 0
     
            this.state = {
                'total':        total, 
                'offSetX':      offSetX,
                'currentIndex': props.defaultIndex,
    }
    }
     
        componentWillMount() {
            /**
    * 组件第一次绘制之前调用。render前
    * 可以更新state参数
    */
        
    }
        
        componentDidMount() {
            /**
    * 在组件第一次绘制后调用,通知组件以及加载完成。render 后
    */
    }
     
     
        scrollviewDidScroll(e) {
            let setX = e.nativeEvent.contentOffset.x
            
            if (setX == 0) {
                this.setState({
                    'offSetX': this.props.componentWidth * this.state.total
    })
     
    } else if (setX == this.props.componentWidth * (this.state.total + 1)) {
                this.setState({
                    'offSetX': this.props.componentWidth
    })
    }
    }
     
        scrollEndDrag(e) {
            let setX = e.nativeEvent.contentOffset.x
            this.setState({
                'offSetX': setX
    })
    }
     
        momentumScrollEnd(e) {
            let setX = e.nativeEvent.contentOffset.x; 
            //求出当前页数 
            let pageIndex = Math.floor(setX / this.props.componentWidth); 
           
            if (pageIndex == 0) {
                this.setState({
                    'currentIndex':this.state.total-1
    })
    } else if (pageIndex == this.state.total+1) {
                this.setState({
                    'currentIndex':0
    })
    } else {
                this.setState({
                    'currentIndex':pageIndex - 1
    })
    }
    }
     
     
        renderPageControl() {
            let pageArray = [];
            let colorStyle;
            
            for (let i = 0; i < this.state.total; i++) {
                colorStyle = (i == this.state.currentIndex) ? {color:'red'} : {color:'white'}
                pageArray.push(
                    <Text key = {i} style = {[{fontSize:30}, colorStyle]}>

                    </Text>
    );
    }
            return pageArray;
    }
     
     
        render() {
     
            let pages = []
     
            if (this.state.total > 1) {
     
                /** children 可以理解为组件上面所有子组件 (如下:Text、Image就可理解为children)
    * <View>
    * <Text></Text>
    * <Image></Image>
    * </View>
    */
                // Object.keys() 返回对象的可列举属性或方法
                pages = Object.keys(this.props.children) // 0,1,2,3
                pages.unshift(this.state.total - 1 + '') // 首位插入 (total-1)===>>> 3,0,1,2,3 
                pages.push('0') // 末尾追加 '0' ===>>> 3,0,1,2,3,0
     
                pages = pages.map((page, i) => {
                    return <View style={{  this.props.componentWidth,height: this.props.componentHeight}}
                                 key={i}>
    {this.props.children[page]}
                           </View>
    })
    }
            
     
            return (
                <View style = {{position: 'relative',  this.props.componentWidth,height: this.props.componentHeight}}>
                    <ScrollView ref = 'scrollView' 
                                backgroundColor = 'black'
                                contentContainerStyle = {{flexDirection:'row',height:this.props.componentHeight}}
                                showsHorizontalScrollIndicator = {true}
                                horizontal={true} // 所有的的子视图会在水平方向上排成一行,默认值为false。
                                pagingEnabled = {true} 
                                keyboardDismissMode = {'on-drag'} // 当拖拽开始的时候隐藏软键盘
                                keyboardShouldPersistTaps = {false} // 当此属性为false的时候,点击焦点文本输入框以外的地方,键盘就会隐藏。
                                iosautomaticallyAdjustContentInsets = {false} // 与OC呼应,顶部莫名出现白色区域
                                contentOffset = {{x:this.state.offSetX, y:0}}
                                scrollsToTop = {false} // 点击状态栏滚动到顶部
                                scrollEventThrottle = {16} // 与 onScroll 方法搭配使用(系统提示建议16)
                               onScroll = {(e)=>this.scrollviewDidScroll(e)}
                                onScrollEndDrag = {(e) => this.scrollEndDrag(e)}
                                onMomentumScrollEnd = {(e)=>this.momentumScrollEnd(e)}>
    {pages}
                     </ScrollView>
                     <View style={{position: 'absolute',
                                   bottom: 30,
                                   left: 0,
                                   right: 0,
                                   flexDirection: 'row',
                                   flex: 1,
                                   justifyContent: 'center',
                                   alignItems: 'center',
                                   backgroundColor: 'black'
    }}>
    {this.renderPageControl()}
                     </View>
                </View>
    )
    }
    }
     
    AppRegistry.registerComponent('ImageLoopPlayer', () => ImageLoopPlayer)
     

     

  • 相关阅读:
    用纯CSS改变下拉列表Select框的默认样式
    前端JS来控制选中的项
    Display:table;妙用,使得左右元素高度相同
    服务器与浏览器缓存协商控制机制的总结
    浏览器缓存机制
    高性能网站建设指南总结
    主题:关于CSS细节集合(一)
    [译] 关于CSS中的float和position
    常用前端开发工具合集
    [JavaScript忍者系列] — CSS选择符引擎入门
  • 原文地址:https://www.cnblogs.com/madaha/p/7598563.html
Copyright © 2020-2023  润新知