react-native上下滚动组件封装

import React, {Component} from ‘react’
import {
Text,
View,
Animated,
Easing,
StyleSheet,
} from ‘react-native’

export default class ScrollVertical extends Component {
static defaultProps = {
enableAnimation: true,
};

constructor(props) {
    super(props);
    let translateValue= new Animated.ValueXY({x: 0, y: 0});
    translateValue.addListener(({x,y})=>{
        // Log('value',x,y)
    });
    this.state = {
        translateValue: translateValue,
        // 滚屏高度
        scrollHeight: this.props.scrollHeight || 32,
        // 滚屏内容
        kb_content: [],
        // Animated.View 滚动到的 y轴坐标
        kb_tempValue: 0,
        // 最大偏移量
        kb_contentOffsetY: 0,
        // 每一次滚动切换之前延迟的时间
        delay: this.props.delay || 500,
        // 每一次滚动切换的持续时间
        duration: this.props.duration || 500,
        enableAnimation: true,
    }
}

render() {
    return (
        <View style={[styles.kbContainer, {height: this.state.scrollHeight}, this.props.kbContainer]}>
            {
                this.state.kb_content.length !== 0 ?
                    <Animated.View
                        style={[
                            {flexDirection: 'column'},
                            {
                                transform: [
                                    {translateY: this.state.translateValue.y}
                                ]
                            }
                        ]}>
                        {this.state.kb_content.map(this._createKbItem.bind(this))}
                    </Animated.View> : null
            }
        </View>
    )
}

componentWillReceiveProps(nextProps) {
    this.setState({
            enableAnimation: nextProps.enableAnimation?true:false
        }, () => {
            this.startAnimation();
        }
    )
}

componentDidMount() {
    let content = this.props.data || [];
    console.log("========================");
    console.log(content);
    if (content.length !== 0) {
        let h = (content.length + 1) * this.state.scrollHeight;
        this.setState({
            kb_content: content.concat(content[0]),
            kb_contentOffsetY: h
        });

        // 开始动画
        // this._startAnimation()
        this.startAnimation();
    }
}


_createKbItem(kbItem, index) {
    return (
        <View key={index}
              style={[{ justifyContent: 'center', height: this.state.scrollHeight}, this.props.scrollStyle]}>
            <Text
                numberOfLines={1}
                ellipsizeMode='tail'
                style={[styles.kb_text_c, this.props.textStyle]}>{kbItem.content}</Text>
        </View>
    )
}

startAnimation = () => {
    if (this.state.enableAnimation) {
        if(!this.animation){
            this.animation = setTimeout(() => {
                this.animation=null;
                this._startAnimation();
            }, this.state.delay);
        }
    }
};

componentWillUnmount() {
    if (this.animation) {
        clearTimeout(this.animation);
    }
    if(this.state.translateValue){
        this.state.translateValue.removeAllListeners();
    }
}

_startAnimation = () => {
    this.state.kb_tempValue -= this.state.scrollHeight;
    if (this.props.onChange) {
        let index = Math.abs(this.state.kb_tempValue) / (this.state.scrollHeight);
        this.props.onChange(index<this.state.kb_content.length-1?index:0);
    }
    Animated.sequence([

        // Animated.delay(this.state.delay),
        Animated.timing(
            this.state.translateValue,
            {
                isInteraction: false,
                toValue: {x: 0, y: this.state.kb_tempValue},
                duration: this.state.duration, // 动画持续的时间(单位是毫秒),默认为500
                easing: Easing.linear
            }
        ),
    ])
        .start(() => {
            if (this.state.kb_tempValue - this.state.scrollHeight === -this.state.kb_contentOffsetY) {
                // 快速拉回到初始状态
                this.state.translateValue.setValue({x: 0, y: 0});
                this.state.kb_tempValue = 0;
            }
            this.startAnimation();



        })
}

}

const styles = StyleSheet.create({
kbContainer: {
// 必须要有一个背景或者一个border,否则本身高度将不起作用
backgroundColor: ‘transparent’,
overflow: ‘hidden’
},
kb_text_c: {
fontSize: 18,
color: ‘#181818’,
}
});

新建一个文件把代码拷进去,用的时候参照下
新建一个文件把代码拷进去,用的时候参照下面

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值