react native 弹框设计,兼容IOS和Android

1.实现的效果

- 点击按钮,出现弹框,最好有动画;

- 点击弹框周围,弹框消失;

- 点击Android返回键,弹框消失;

- 有“取消”和“确定”按钮,回调函数,巴拉巴拉巴。。。。

2.实现思路

- 弹框外层组件使用Modal,免得监听安卓返回键;

- 动画使用Animated;

- 最外层(绝对定位)存在一个宽高等于手机屏幕的activeOpacity=1的TouchableOpacity,点击能够使Modal消失;

3.源码

Popover.js

/**
 * 弹框 
 * @flow
 */

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  BackHandler,
  Modal,
  Button,
  TouchableOpacity,
  Animated,
  Image,
  StatusBar
} from 'react-native';

import PropTypes from 'prop-types';
import theme from '../utils/theme';
const {screenWidth, screenHeight, segment} = theme;

export default class Popover extends Component {
  
  constructor(props){
    super(props);
    this.state = {
      show: false,
      pageX: 0,
      pageY: 0,
      height: 0,
      scaleAnimationValue: new Animated.Value(0)
    }
  }
  // 打开弹框
  showModal() {
    this.setState({
      show: true,
    });

    if(this.props.useAnimation){
      Animated.spring(this.state.scaleAnimationValue, {
          toValue: 1,
          duration: 200,
      }).start();
    }

  }
  // 关闭弹框
  onRequestClose() {
    if(this.props.useAnimation){
      this.state.scaleAnimationValue.setValue(0);
    }
    this.setState({
      show: false
    });
  }

  render() {
    const {hasCancelBtn, cancelCallback, title, content, ensureCallback, useAnimation, takePicsCallback, albumCallback, wordsCallback, hasWordBtn} = this.props;
    return (
      
         this.onRequestClose()}>

           this.onRequestClose()}
          >
            
          

          
            
              
              {
                this.props.onlyInChose ?
                
                  
                    
                      
                      拍摄照片
                      
                    
                  
                  
                    
                      
                      相册选择
                      
                    
                  
                  {
                    hasWordBtn &&
                    
                      
                        
                        文字说说
                        
                      
                    
                  }
                
                :
                
                  
                    {title}
                  

                  
                    {content}
                  
                
              }
                
            
            {
              this.props.onlyInChose ? 
              null
              :
              
                {
                  hasCancelBtn && 
                   {
                        this._close();
                        // 取消后的事件
                        cancelCallback && cancelCallback()
                      }}
                  >
                      取消
                  
                }
                
                 {
                        this.onRequestClose();
                        // 子组件传递数据到父组件 
                        ensureCallback && ensureCallback();
                    }}
                >
                    确定
                
              
            }
          
        
      
    );
  }

  _close() {
    this.onRequestClose();
  }

  ensureCallback() {
    this.props.navigation.goBack(null);
  }

}

Popover.propTypes = {
  hasCancelBtn: PropTypes.bool,      // 是否保留“取消”按钮
  onlyInChose: PropTypes.bool,       // 是否应用在发布说说时
  cancelCallback: PropTypes.func,    // 点击取消后的回调
  ensureCallback: PropTypes.func,    // 点击确定后的回调
  wordsCallback: PropTypes.func,     // 点击发布说说回调
  albumCallback: PropTypes.func,     // 选取相册回调
  takePicsCallback: PropTypes.func,  // 拍摄照片回调
  title: PropTypes.string,           // 提示标题
  content: PropTypes.string,         // 提示内容文字
  useAnimation: PropTypes.bool,      // 是否应用动画
  hasWordBtn: PropTypes.bool         // 是否包含说说
}
Popover.defaultProps = {
  hasCancelBtn: true,
  title: '未定义标题',
  content: '未定义内容',
  onlyInChose: false,
  useAnimation: false,
  hasWordBtn: true
}

const styles = StyleSheet.create({
  modalContainer: {
    position: 'absolute',
    width: screenWidth,
    zIndex: -1,
    height: Platform.OS == 'android' ? screenHeight - StatusBar.currentHeight : screenHeight - 20,
  },
  outerContainer: {
    position: 'absolute',
    width: screenWidth,
    height: screenHeight,
    backgroundColor: 'rgba(1, 1, 1, 0.5)'
  },
  container: {
    width: theme.scaleSize(660),
    backgroundColor: '#fff',
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
    position: 'absolute',
    top: theme.scaleSize(410),
    left: (screenWidth - theme.scaleSize(660)) / 2,
  },
  promptContainer: {
    width: theme.scaleSize(660),
    alignItems: 'center',
  },
  choseContainer:{

  },
  choseItem:{
    height: theme.scaleSize(120),
    width: theme.scaleSize(660),
    paddingHorizontal: theme.scaleSize(160),
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    borderBottomWidth: segment.width,
    borderBottomColor: '#999999',
  },
  titleContainer:{
    width: theme.scaleSize(660),
    height: theme.scaleSize(116),
    borderBottomColor: '#F2F2F2',
    borderBottomWidth: segment.width,
    justifyContent: 'center',
    alignItems: 'center'
  },
  contentContainer:{
    width: theme.scaleSize(660),
    height: theme.scaleSize(246),
    padding:theme.scaleSize(40),
    // justifyContent: 'center',
    alignItems: 'center'
  },
  buttonContainer: {
    height: theme.scaleSize(100),
    width: theme.scaleSize(660),
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    borderTopWidth: segment.width,
    borderColor: '#999999'
  },
  center: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  line: {
    height: theme.scaleSize(100),
    width: segment.width,
    backgroundColor: '#999999'
  }
});


效果图:
react native 弹框设计,兼容IOS和Android_第1张图片
1212121212.gif

你可能感兴趣的:(react native 弹框设计,兼容IOS和Android)