React-native/React 公告滚动组件(原生代码)
编写不易, 希望大家点赞
import React, {PureComponent} from 'react';
import {Animated, Easing, View} from 'react-native';
export default class NoticeScroll extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      newChildren: this.props.children,
    };
    this.animation = new Animated.Value();
    this.direction = this.props.direction === 'vertical' ? 'height' : 'width';
    this.transationValue = this.props.styles[this.direction];
    this.key = ;
    this.arr = [];
  }
  startAnimation() {
    const meter = this.props.meter || ;
    Animated.timing(this.animation, {
      toValue: -this.transationValue + meter,
      duration: this.props.scrolltime || ,
      easing: Easing.linear,
      useNativeDriver: true,
    }).start(() => {
      this.animation = new Animated.Value();
      this.initPosition();
      this.startAnimation();
    });
  }
  initPosition() {
    this.key++;
    if (this.key < ) {
      // React.Children.forEach(this.props.children, (child, index) => {
      //     let props = {
      //         key: `${this.key}${index}`,
      //         ...child.props
      //     };
      //     this.arr.push(React.cloneElement(child, props));
      // });
      React.Children.forEach(this.props.children, (child, index) => {
        let newProps = {
          key: `${this.key}${index}flag`,
          ...child.props,
        };
        this.arr.push(React.cloneElement(child, newProps));
      });
    }
    this.setState({
      newChildren: [...this.arr],
    });
  }
  componentDidMount() {
    this.initPosition();
    this.startAnimation();
  }
  componentWillUnmount() {
    this.startAnimation = () => {};
  }
  render() {
    const {styles, direction} = this.props;
    const {newChildren} = this.state;
    return (
      <View style={{overflow: 'hidden', height: , justifyContent: 'center'}}>
        <Animated.View
          style={{
            transform: [
              direction !== 'vertical'
                ? {translateX: this.animation}
                : {translateY: this.animation},
            ],
            flexDirection: 'row',
          }}>
          {newChildren}
        </Animated.View>
      </View>
    );
  }
}
组件可以在React中直接使用,把Animated.View 改成Animated.div即可
此代码有一个不好的地方,就是只能读取本地的,否则会有延迟
优化代码!!!
import React, { Component } from 'react';
import { View, Animated, Easing, Text, TouchableOpacity, InteractionManager } from 'react-native';
const styles = {
    bgContainerStyle : {
        flexDirection : 'row',
        alignItems : 'center',
        justifyContent : 'flex-start',
        backgroundColor : '#FFFFFF',
        overflow : 'hidden'
    },
    textMeasuringViewStyle: {
        flexDirection : 'row',
        opacity : ,
    },
    textMeasuringTextStyle: {
        fontSize : ,
    },
    textStyle : {
        fontSize : ,
        color : '#000000',
    }
};
export default class ScrollAnnounce extends Component {
    constructor(props) {
        super(props);
        this.state = {
            animation : null,
            textList : [],
            textWidth : ,
            viewWidth : ,
            start:false
        }
    }
    static defaultProps = {
        duration : ,
        speed : ,
        textList : [],
        width : ,
        height : ,
        direction : 'left',
        reverse : false,
        separator : ,
        onTextClick : () => {},
    }
    componentWillMount(){
        this.setState({
            textList : this.props.textList || [],
        })
        this.animatedTransformX = new Animated.Value();
    }
    componentDidUpdate(){
        let { textWidth, viewWidth } = this.state;
        let { duration, speed, width, direction } = this.props;
        let mDuration = duration;
        if(speed && speed > ){
            mDuration = (width + textWidth) / speed * ;
        }
        if(!this.state.animation && textWidth && viewWidth){
            this.animatedTransformX.setValue(direction == 'left' ? width : (direction == 'right' ? -textWidth : width));
            this.setState({
                animation : Animated.timing(this.animatedTransformX, {
                    toValue: direction == 'left' ? -textWidth : (direction == 'right' ? width : -textWidth),
                    duration: mDuration,
                    useNativeDriver: true,
                    easing: Easing.linear,
                }),
            }, () => {
                this.state.animation && this.state.animation.start(() => {
                    this.setState({
                        animation: null,
                    });
                });
            })
        }
    }
    componentWillReceiveProps(nextProps){
        let newText = nextProps.textList || [];
        let oldText = this.props.textList || [];
        if (newText !== oldText) {
            this.state.animation && this.state.animation.stop();
            this.setState({
                textList : newText,
                animation: null,
                start:true
            });
        }
    }
    componentWillUnmount(){
        this.state.animation && this.state.animation.stop();
    }
    textOnLayout = (e) => {
        let width = e.nativeEvent.layout.width;
        let { textList, separator } = this.props;
        this.setState({
            textWidth : width + ((textList.length - ) * separator),
        })
    }
    viewOnLayout = (e) => {
        let width = e.nativeEvent.layout.width;
        this.setState({
            viewWidth : width,
        })
    }
    textView(list){
        let { textStyle, onTextClick, reverse, separator } = this.props;
        let itemView = [];
        for(let i = ;i<list.length;i++){
            let item = list[i];
            if(reverse){
                item.value = item.value.split("").reverse().join("");
            }
            itemView.push(
                <TouchableOpacity key = {''+i} activeOpacity = {0.9} onPress = {() => {
                    onTextClick(item)
                }}>
                    <View style = {{flexDirection : 'row',marginRight : i < list.length -  ? separator : }}>
                        <Text style = {{
                            ...styles.textStyle,
                            ...textStyle
                        }}
                              numberOfLines = {}
                        >{item.value}</Text>
                    </View>
                </TouchableOpacity>
            );
        }
        return(
            <Animated.View
                style = {{flexDirection : 'row',width : this.state.textWidth,transform: [{ translateX: this.animatedTransformX }]}}
                onLayout={(event) => this.viewOnLayout(event)}
            >
                {itemView}
            </Animated.View>
        )
    }
    textLengthView(list){
        let { textStyle } = this.props;
        let text = '';
        for(let i = ;i<list.length;i++){
            text += list[i].value;
        }
        return(
            <View style = {{
                ...styles.textMeasuringViewStyle,
                width : list.length *
            }}>
                <Text style = {{
                    ...styles.textMeasuringTextStyle,
                    ...textStyle
                }}
                      onLayout={(event) => this.textOnLayout(event)}
                      numberOfLines = {}
                >{text}</Text>
            </View>
        )
    }
    render(){
        let { width, height, bgContainerStyle } = this.props;
        let { textList,start } = this.state;
        return(
            <View style = {{
                ...styles.bgContainerStyle,
                width : width,
                height : height,
                ...bgContainerStyle,
            }} opacity = {this.state.animation ?  : }>
                {start&&this.textView(textList) }
                {start&&this.textLengthView(textList) }
            </View>
        )
    }
}
ScrollAnnounce
<ScrollAnnounce
textList = {noticeList}
speed = {}
width = {Platform.OS==='ios'?autoWidth():autoWidth()}
height = {}
direction = {'left'}
reverse = {false}
bgContainerStyle = {{backgroundColor : '#f8f8f8'}}
textStyle = {{fontSize : ,color : '#D1B793'}}
onTextClick = {(item) => {
this._toDetail(item)
}}
/>
React-native/React 公告滚动组件(原生代码)的更多相关文章
- 深入浅出 React Native:使用 JavaScript 构建原生应用
		深入浅出 React Native:使用 JavaScript 构建原生应用 链接:https://zhuanlan.zhihu.com/p/19996445 原文:Introducing React ... 
- [RN] React Native代码转换成微信小程序代码的转换引擎工具
		React Native代码转换成微信小程序代码的转换引擎工具 https://github.com/areslabs/alita 
- React Native 项目常用第三方组件汇总
		React Native 项目常用第三方组件汇总 https://www.jianshu.com/p/d9cd9a868764?utm_campaign=maleskine&utm_conte ... 
- React Navigation & React Native & React Native Navigation
		React Navigation & React Native & React Native Navigation React Navigation https://facebook. ... 
- React Native:使用 JavaScript 构建原生应用
		[转载] 本篇为联合翻译,译者:寸志,范洪春,kmokidd,姜天意 数月前,Facebook 对外宣布了正在开发的 React Native 框架,这个框架允许你使用 JavaScript 开发原生 ... 
- React Native知识5-Touchable类组件
		React Native 没有像web那样可以给元素绑定click事件,前面我们已经知道Text组件有onPress事件,为了给其他组件 也绑定点击事件,React Native提供了3个组件来做这件 ... 
- React Native:使用 JavaScript 构建原生应用 详细剖析
		数月前,Facebook 对外宣布了正在开发的 React Native 框架,这个框架允许你使用 JavaScript 开发原生的 iOS 应用——就在今天,Beta 版的仓库释出了! 基于 Pho ... 
- Facebook 开源安卓版 React Native,开发者可将相同代码用于网页和 iOS 应用开发
		转自:http://mt.sohu.com/20150915/n421177212.shtml Facebook 创建了React Java 库,这样,Facebook 的工程团队就可以用相同的代码给 ... 
- React Native 之 定义的组件 (跨文件使用)
		哈哈的~~~今天介绍的是自定义组件 然后去使用这个组件,让这个组件传递这各种文件之间 哈哈 下面开始吧!!!! 我们所要创建的是一个自定义的Button,先创建一个js文件起名为MyButton, ... 
随机推荐
- Luogu P3810 【模板】三维偏序(陌上花开) CDQ分治 树状数组
			https://www.luogu.org/problemnew/show/P3810 复习板子,重要的题就真的要写三遍???之前写过一篇博客了,不过之前写的那个板子的sort用的规则真是沙雕 #in ... 
- Codevs 3160 最长公共子串(后缀数组)
			3160 最长公共子串 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长 ... 
- Cogs 2546. 取石块儿(博弈)
			取石块儿 ★ 输入文件:tstones.in 输出文件:tstones.out 简单对比 时间限制:1 s 内存限制:256 MB 问题描述 小L和小T进行取石块儿游戏,给定一个整数n表示石块儿总数, ... 
- Educational Codeforces Round 64 部分题解
			Educational Codeforces Round 64 部分题解 不更了不更了 CF1156D 0-1-Tree 有一棵树,边权都是0或1.定义点对\(x,y(x\neq y)\)合法当且仅当 ... 
- UOJ#318. 【NOI2017】蔬菜 贪心
			原文链接 www.cnblogs.com/zhouzhendong/p/UOJ318.html 前言 我怎么越来越菜了.先是题目读错,想了个李超树假算法,然后读懂题之后没了耐心直接贺题.然后发现我数据 ... 
- Java SpringBoot Scheduled定时任务
			package task.demo.controller; import org.springframework.beans.factory.annotation.Autowired; import ... 
- [Shell]利用JS文件反弹Shell
			0x01 模拟环境 攻击: kali ip: 192.168.248.132 测试: windows 7 x64 ip: 192.168.248.136 0x02 工具地址 https://githu ... 
- php手记之07-tp5 cookie与session
			ThinkPHP采用 01-think\facade\Cookie类提供Cookie支持. 02-think\Cookie 配置文件位于 config/cookie.php中,一般会配置一个超时时间. ... 
- qt creator中常用快捷键
			激活欢迎模式 Ctrl + 1 激活编辑模式 Ctrl + 2 激活调试模式 Ctrl + 3 激活项目模式 Ctrl + 4 激活帮助模式 Ctrl + 5 激活输出模式 Ctrl + 6 查找当前 ... 
- 优化Unity游戏项目的脚本(上)
			本文将由捷克独立游戏工作室Lonely Vertex的开发工程师Ondřej Kofroň,分享C#脚本的一系列优化方法,并提供改进Unity游戏性能的最佳实践. 在开发游戏时,我们遇到了游戏过程中偶 ... 
