react-native顶部/底部弹窗效果

  • 此组件基于通用弹窗组件,将完整代码复制到项目即可:https://blog.csdn.net/qq_38545425/article/details/121922005

组件都是函数式掉用方法,个人感觉还好用,暂时不知道这种方式有没有什么缺点

  • 先上效果,图一是基于当前文章的组件进行了再次封装,如有需要的小伙伴可以留言,后续发文介绍
    在这里插入图片描述
    在这里插入图片描述

上完整代码

  • DrawerModal.js
import React from 'react';
import {
  Text,
  Animated,
  Easing,
  InteractionManager,
  TouchableOpacity
} from 'react-native';
import PropTypes from 'prop-types';
import {destroyLastSibling, showModal} from '../showModal/ShowModal';
import {getScreenHeight, getScreenWidth} from '../../utils/util';

let ref = null;

/**
  *显示弹窗方法、
  * component: 显示的组件
  * height: 组件弹出高度,不包括蒙层,蒙层默认全屏。弹出高度的问题暂时不知道怎么解决,有大佬可以留言
  * showType: 弹出方式,'bottom', 'top'
  * bgHid: 点击蒙层是否隐藏
**/
export const showDrawerModal = ({component = null, height = null, showType = null, bgHid = true}) => {
  showModal(<DrawerModal
    component={component}
    ref={e => ref = e}
    height={height}
    showType={showType}
    bgHid={bgHid}
  />);
};
/**
  *	关闭弹窗----在合适的地方掉用
  **/
export const closeDrawerModal = () => {
  ref && ref.close && ref.close();
  ref = null;
};

class DrawerModal extends React.Component {
  animated = new Animated.Value(0);

  static propTypes = {
    component: PropTypes.any,
    height: PropTypes.number,
    showType: PropTypes.oneOf(['bottom', 'top'])
  };

  static defaultProps = {
    component: <Text>请传入组件</Text>,
    height: 200,
    showType: 'bottom'
  };

  componentDidMount(): void {
    InteractionManager.runAfterInteractions(() => {
      Animated.timing(this.animated, {
        toValue: 1,
        duration: 200,
        easing: Easing.ease
      }).start();
    });
  }

  close = () => {
    Animated.timing(this.animated, {
      toValue: 0,
      duration: 200,
      easing: Easing.ease
    }).start(() => destroyLastSibling());
  };

  render() {
    const height = this.animated.interpolate({
      inputRange: [0, 1],
      outputRange: [0, this.props.height]
    });
    const opct = this.animated.interpolate({
      inputRange: [0, 1],
      outputRange: [0, 0.4]
    });
    return (
      <>
        <Animated.View
          style={{
            position: 'absolute',
            opacity: opct,
            flex: 1,
            top: 0
          }}
        >
          <TouchableOpacity
            activeOpacity={1}
            onPress={() => {
              if (!this.props.bgHid) return;
              this.close();
            }}
            style={{
              width: getScreenWidth(),
              backgroundColor: '#000',
              height: getScreenHeight() + 100
            }}
          />
        </Animated.View>
        <Animated.View
          style={this.props.showType === 'bottom' ? {
            height: height,
            position: 'absolute',
            bottom: 0
          } : {
            marginTop: height,
            position: 'absolute',
            top: -this.props.height
          }}>
          {this.props.component}
        </Animated.View>
      </>
    );
  }
}

使用方式

  • 创建自己要显示的组件
import React from 'react';
import {View, Text, } from 'react-native';
import {closeDrawerModal} from 'DrawerModal';

export default class TestDemo extends React.Component{
  render(){
    return <View>
      <Text>底部弹窗</Text>
      <TouchableOpacity
      	onPress = {() => closeDrawerModal()}
      >
      	 <Text>关闭弹窗</Text>
      </TouchableOpacity>
    </View>
  }
}
  • 显示弹窗
showDrawerModal({
  component: <TestDemo />,
  height: 250,
  showType: 'bottom'
});
  • 关闭弹窗
//在需要关闭的地方直接掉用
closeDrawerModal()

组件可能不是很完善,觉得可以的小伙伴自取

  • 原文:https://blog.csdn.net/qq_38545425/article/details/121947368
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值