天天看點

ReactNative 側滑菜單的實作

  側滑菜單在App的架構結構非常常見和實用,本篇部落格,是用reactNative實作了一個側滑的基本的架構,但具體的菜單欄需要各位看官的去自行添加了

實作的思路 tab+定時器+Animated.View的方式

import React, { Component, PropTypes } from 'react'
import {
  View, Text, StyleSheet,
  TouchableHighlight, Animated,
  Platform, Dimensions, Image
} from "react-native"


const WINDOW = Dimensions.get('window')
var closeTimeoutId = null

export default class MyInfo extends Component {
  static propTypes = {
    onClose: PropTypes.func,
    onCancel: PropTypes.func,
    showCancel: PropTypes.bool
  }
  static defaultProps =  {
    onClose: null,
    onCancel: null,
    closeInterval: 4000,
    showCancel: false,

  }
  constructor(props) {
    super(props)
    this.state = {
      animationValue: new Animated.Value(0),
      duration: 450,
      isOpen: false,
      topValue: 0
    }
    // Render
    this.renderButton = this.renderButton.bind(this)
    this.renderDropDown = this.renderMyinfo.bind(this)
    // Action
    this.alert = this.alert.bind(this)
    this.dismiss = this.dismiss.bind(this)
    this.onCancel = this.onCancel.bind(this)
    this.onClose = this.onClose.bind(this)
    // Util
    this.animate = this.animate.bind(this)

  }

  alert() {

    if (this.state.isOpen) {
      this.dismiss()
      return
    }
    if (this.state.isOpen == false) {
      this.setState({
        isOpen: true,
        topValue: 0
      })
    }
    this.animate(1)
     if (this.props.closeInterval > 1) {
      closeTimeoutId = setTimeout(function() {
        this.onClose()
      }.bind(this), this.props.closeInterval)
    }
  }
  dismiss(onDismiss) {
    if (this.state.isOpen) {
      if (closeTimeoutId != null) {
        clearTimeout(closeTimeoutId)
      }
      this.animate(0)
      setTimeout(function() {
        if (this.state.isOpen) {
          this.setState({
            isOpen: false
          })
          if (onDismiss) {
   
            onDismiss('warn')
          }
        }
      }.bind(this), (this.state.duration))
    }
  }
  onClose() {
    this.dismiss(this.props.onClose)
  }
  onCancel() {
    this.dismiss(this.props.onCancel)
  }
  animate(toValue) {
    Animated.spring (
      this.state.animationValue, {
        toValue: toValue,
        duration: this.state.duration,
        friction: 9
      }
    ).start()
  }


  
  renderButton( onPress, isRendered) {
    if ( isRendered) {
      return (
         <View style={{top:0,width:WINDOW.width,height:WINDOW.height,backgroundColor:'green'}}>

             <TouchableHighlight  onPress={onPress} >
               <Image style={styles.cancelBtnImageStyle} source={require('./assets/cancel.png')} />

              </TouchableHighlight>
         </View>

    
      )
    }
    return null
  }
  renderMyinfo(isOpen) {
    if (isOpen == true) {

          style = {backgroundColor: '#cd853f'}

      return (
          <Animated.View
           ref={(ref) => this.mainView = ref}
           style={{
              transform: [{
                translateX: this.state.animationValue.interpolate({
                  inputRange: [0, 1],
                  outputRange: [-WINDOW.width, 0]
                }),
              }],
              position: 'absolute',
              top: this.state.topValue,
              left: 0,
              right: 0
            }}>
              <View style={ {backgroundColor: '#cd853f'}}>
                {this.renderButton(  this.onCancel, this.props.showCancel)}
              </View>
          </Animated.View>
      )
    }
    return null
  }
  render() {
    return (
      this.renderMyinfo(this.state.isOpen)
    )
  }
}

let styles= StyleSheet.create({
    cancelBtnImageStyle: {
      position:'absolute',
      right:10,
      padding: 8,
      width: 40,
      height: 40,
    }

})
           
ReactNative 側滑菜單的實作

調用

showMyinfo(){

      this.myinfo.alert()

    }

    render(){

        return (

            <View >

                <Nav MyBtnPress={()=>{this.showMyinfo()}}/>

                 <Myinfo ref={myinfo => this.myinfo = myinfo }

            closeInterval={0}

          onClose={(data) => this.onClose(data)}

          onCancel={(data) => this.onClose(data)}

          showCancel={true}

                 />

            </View>

        );

    }

  closeAlert() {

    this.myinfo.onClose()

  }

  onClose(data) {

    console.log(data)

  }