React Native 通告消息竖向轮播组件的封装


Posted in Javascript onAugust 25, 2020

本文实例为大家分享了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) {
  Log('componentWillReceiveProps', nextProps)
   this.setState({
     enableAnimation: nextProps.enableAnimation?true:false
    }, () => {
     this.startAnimation();
    }
   )
 }

 componentDidMount() {
  Log('componentDidMount')
  let content = this.props.data || []
  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 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(() => {
    // 无缝切换
    // Log('end')
    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',
 }

使用

import React, {Component} from 'react';
import {
 StyleSheet,
 View,
 TouchableOpacity,
 Alert,
 ScrollView,
 ART,
 TouchableHighlight,
 ListView,
 Dimensions,
 Text
} from 'react-native';

import ScrollVertical from '../../app-widget/scroll-vertical'


const dataArray = [
 {
  title: '降价了',
 },
 {
  title: '全场五折',
 },
 {
  title: '打到骨折',
 }
]
export default class extends React.Component {

 render() {
  let array = [{ content: '' }];
  if (dataArray && dataArray.length > 0) {
   array = [];
   for (let item of dataArray) {
    array.push({ content: item.title});
   }
  }
  return (
   <View style={{ padding: Constant.sizeMarginDefault, paddingBottom: 0, backgroundColor: '#FFFFFF' }}>
    <TouchableOpacity onPress={() => {
     if (dataArray && dataArray.length > 0) {
      Log(dataArray[this.index].title)
     }
    }} style={{ flexDirection: 'row', backgroundColor: "#FFFFFF", alignItems: 'center', borderRadius: 8, paddingLeft: 5, paddingRight: 5 }}>
     <Text style={{ fontSize: Constant.scaleFontSize(14) }} fontWeight={'bold'}>公告</Text>
     <View style={{ marginLeft: 5, marginRight: 8, backgroundColor: '#b01638', borderRadius: 8, width: 22, alignItems: 'center', }}>
      <Text style={{ color: 'white', fontSize: Constant.fontSizeSmall }}>新</Text>
     </View>
     <View style={{ flexDirection: 'row', flex: 1 }}>
      <ScrollVertical
       onChange={(index => {
        this.index = index;
       })}
       enableAnimation={true}
       data={array}
       delay={2500}
       duration={1000}
       scrollHeight={34}
       scrollStyle={{ alignItems: 'flex-start' }}
       textStyle={{ color: Constant.colorTxtContent, fontSize: Constant.fontSizeSmall }} />
     </View>
     <View style={{ height: 14, width: 1, backgroundColor: Constant.colorTxtContent }} />
     <Text style={{ color: Constant.colorTxtContent, paddingLeft: Constant.sizeMarginDefault, fontSize: Constant.fontSizeSmall }}>查看</Text>
    </TouchableOpacity>
   </View>
  );

 }
};

React Native 通告消息竖向轮播组件的封装

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
转一个日期输入控件,支持FF
Apr 27 Javascript
Jquery下attr和removeAttr的使用方法
Dec 28 Javascript
Jquery选择子控件&quot;大于号&quot;和&quot; &quot;区别介绍及使用示例
Jun 25 Javascript
jQuery获取Radio,CheckBox选择的Value值(示例代码)
Dec 12 Javascript
JavaScript模拟实现继承的方法
Mar 30 Javascript
Bootstrap布局之栅格系统详解
Jun 13 Javascript
微信小程序学习笔记之本地数据缓存功能详解
Mar 29 Javascript
解决layui富文本编辑器图片上传无法回显的问题
Sep 18 Javascript
vue监听用户输入和点击功能
Sep 27 Javascript
Vue watch响应数据实现方法解析
Jul 10 Javascript
Vue使用axios引起的后台session不同操作
Aug 14 Javascript
toString.call()通用的判断数据类型方法示例
Aug 28 Javascript
Vue v2.5 调整和更新不完全问题
Oct 24 #Javascript
Vue.js 2.5新特性介绍(推荐)
Oct 24 #Javascript
Vue 2.5 Level E 发布了: 新功能特性一览
Oct 24 #Javascript
浅谈在vue项目中如何定义全局变量和全局函数
Oct 24 #Javascript
Angularjs添加排序查询功能的实例代码
Oct 24 #Javascript
详解基于Vue+Koa的pm2配置
Oct 24 #Javascript
Vue.js2.0中的变化小结
Oct 24 #Javascript
You might like
日本因肺炎疫情影响,这几部动漫推延播放!
2020/03/03 日漫
PHP完整的日历类(CLASS)
2006/11/27 PHP
php中文本操作的类
2007/03/17 PHP
PHP实现时间轴函数代码
2011/10/08 PHP
php环境下利用session防止页面重复刷新的具体实现
2014/01/09 PHP
php+ajax实时输入自动搜索匹配的方法
2014/12/26 PHP
php根据某字段对多维数组进行排序的方法
2015/03/07 PHP
PHP实现伪静态方法汇总
2016/01/13 PHP
Zend Framework教程之视图组件Zend_View用法详解
2016/03/05 PHP
不间断滚动JS打包类,基本可以实现所有的滚动效果,太强了
2007/12/08 Javascript
IE和Firefox下javascript的兼容写法小结
2008/12/10 Javascript
IE6,IE7下js动态加载图片不显示错误
2010/07/17 Javascript
根据对象的某一属性进行排序的js代码(如:name,age)
2010/08/10 Javascript
jquery append 动态添加的元素事件on 不起作用的解决方案
2015/07/30 Javascript
Vue.js报错Failed to resolve filter问题的解决方法
2016/05/25 Javascript
JavaScript判断数组重复内容的两种方法(推荐)
2016/06/06 Javascript
JS实现的图片预览插件与用法示例【不上传图片】
2016/11/25 Javascript
nodejs开发——express路由与中间件
2017/03/24 NodeJs
Vue+axios 实现http拦截及路由拦截实例
2017/04/25 Javascript
讲解vue-router之什么是编程式路由
2018/05/28 Javascript
20道JS原理题助你面试一臂之力(必看)
2019/07/22 Javascript
js实现视图和数据双向绑定的方法分析
2020/02/05 Javascript
[12:36]《DOTA2》国服注册与激活指南全攻略
2013/04/28 DOTA
解决Pycharm运行时找不到文件的问题
2018/10/29 Python
50行Python代码获取高考志愿信息的实现方法
2019/07/23 Python
python反编译教程之2048小游戏实例
2021/03/03 Python
CSS3实现网站商品展示效果图
2020/01/18 HTML / CSS
HTML5本地存储localStorage、sessionStorage基本用法、遍历操作、异常处理等
2014/05/08 HTML / CSS
澳大利亚宠物食品和用品商店:PETstock
2020/01/02 全球购物
华为的Java面试题
2014/03/07 面试题
主键(Primary Key)约束和唯一性(UNIQUE)约束的区别
2013/05/29 面试题
商场促销活动方案
2014/02/08 职场文书
继承权公证书范本
2015/01/23 职场文书
社区端午节活动总结
2015/02/11 职场文书
Python学习之时间包使用教程详解
2022/03/21 Python
Python+pyaudio实现音频控制示例详解
2022/07/23 Python