Home  >  Article  >  Web Front-end  >  Detailed explanation of encapsulation of React Native notification message vertical carousel component

Detailed explanation of encapsulation of React Native notification message vertical carousel component

小云云
小云云Original
2018-01-03 13:15:142496browse

This article mainly introduces the encapsulation of the React Native notification message vertical carousel component. It has certain reference value. Interested friends can refer to it. I hope it can help everyone.


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: &#39;column&#39;},
                {
                  transform: [
                    {translateY: this.state.translateValue.y}
                  ]
                }
              ]}>
              {this.state.kb_content.map(this._createKbItem.bind(this))}
            </Animated.View> : null
        }
      </View>
    )
  }

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

  componentDidMount() {
    Log(&#39;componentDidMount&#39;)
    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: &#39;center&#39;, 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(&#39;end&#39;)
        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: &#39;transparent&#39;,
    overflow: &#39;hidden&#39;
  },
  kb_text_c: {
    fontSize: 18,
    color: &#39;#181818&#39;,
  }

Use


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

import ScrollVertical from &#39;../../app-widget/scroll-vertical&#39;


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

  render() {
    let array = [{ content: &#39;&#39; }];
    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: &#39;#FFFFFF&#39; }}>
        <TouchableOpacity onPress={() => {
          if (dataArray && dataArray.length > 0) {
            Log(dataArray[this.index].title)
          }
        }} style={{ flexDirection: &#39;row&#39;, backgroundColor: "#FFFFFF", alignItems: &#39;center&#39;, borderRadius: 8, paddingLeft: 5, paddingRight: 5 }}>
          <Text style={{ fontSize: Constant.scaleFontSize(14) }} fontWeight={&#39;bold&#39;}>公告</Text>
          <View style={{ marginLeft: 5, marginRight: 8, backgroundColor: &#39;#b01638&#39;, borderRadius: 8, width: 22, alignItems: &#39;center&#39;, }}>
            <Text style={{ color: &#39;white&#39;, fontSize: Constant.fontSizeSmall }}>新</Text>
          </View>
          <View style={{ flexDirection: &#39;row&#39;, flex: 1 }}>
            <ScrollVertical
              onChange={(index => {
                this.index = index;
              })}
              enableAnimation={true}
              data={array}
              delay={2500}
              duration={1000}
              scrollHeight={34}
              scrollStyle={{ alignItems: &#39;flex-start&#39; }}
              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>
    );

  }
};

##Related recommendations :

php notice board related issues

React Native verification code countdown sharing

Instance detailed explanation of React Native time Conversion format tool class

The above is the detailed content of Detailed explanation of encapsulation of React Native notification message vertical carousel component. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn