react-native自定义Modal模态框|仿ios、微信弹窗RN版
程序员文章站
2023-02-24 12:57:17
前序 纵观每个优质项目,无论web端还是native原生应用开发,弹窗都是不可忽视的一环,能很大程度上直接决定用户体验。如:微信、支付宝、ios都有很成熟的一套弹窗UI展示场景。 最近一直沉迷在react-native开发研究中,学习起来发现没有想象的难,不过也采坑了不少。鉴于之前有基于h5和小程序 ......
前序
纵观每个优质项目,无论web端还是native原生应用开发,弹窗都是不可忽视的一环,能很大程度上直接决定用户体验。如:微信、支付宝、ios都有很成熟的一套弹窗ui展示场景。
最近一直沉迷在react-native开发研究中,学习起来发现没有想象的难,不过也采坑了不少。鉴于之前有基于h5和小程序技术开发过自定义弹窗的经验,就想着用react-native技术实现msg信息框|alert提示框|confirm确认框|toast弱提示/loading|仿ios、android弹窗,就有了这个rnpop弹窗组件rn版。
效果图
仿真模拟器上画质有些次,真机实测完美,可忽略这一点
看了上图,是不是觉得调用方式还挺多的,没错,很丰富的应用场景
◆ rnpop弹窗组件目录结构
◆ 引入方式及调用
import rnpop from '../utils/rnpop/rnpop.js'
显示:this.refs.rnpop.show({...options});
隐藏:this.refs.rnpop.hide();
/** * --------- react-native弹窗演示(普通型弹窗) --------- */ //msg提示 handlepress01 = ()=> { let rnpop = this.refs.rnpop rnpop.show({ anim: 'fadein', content: 'msg消息提示框(5s后窗口关闭)', shade: true, shadeclose: false, time: 5, xtime: true, }); } //msg提示(黑色背景) handlepress02 = ()=> { let rnpop = this.refs.rnpop rnpop.show({ content: '自定义弹窗背景', shade: false, style: {backgroundcolor: 'rgba(17,17,17,.7)', borderradius: 6}, contentstyle: {color: '#fff', padding: 10}, time: 2 }); }
toast弱提示可自定义loading | success | info | error四种图标
//toast演示 handlepress15 = ()=> { let rnpop = this.refs.rnpop rnpop.show({ skin: 'toast', content: '操作成功', icon: 'success', //success | info | error | loading shade: false, time: 3 }); }
//ios居中对话框 handlepress17 = ()=> { let rnpop = this.refs.rnpop rnpop.show({ skin: 'footer', position: 'center', content: '如果您喜欢探鱼,请给我们个好评,也可以直接反馈意见给我们!', shadeclose: true, btns: [ { text: '给个好评', style: {color: '#30a4fc'}, onpress() { console.log('您点击了给个好评!'); //回调函数 rnpop.show({ anim: 'fadein', content: '感谢您的好评,我们会再接再厉!', shade: true, time: 3 }); } }, { text: '不好用,我要提意见', style: {color: '#30a4fc'}, onpress() { // ... } }, { text: '残忍的拒绝', style: {color: '#30a4fc'}, onpress() { rnpop.close(); } } ] }); }
/** * @title react-native弹窗插件 rnpop-v1.0 beta (utf-8) * @author andy * @create 2019/07/30 10:00:50 gmt+0800 (中国标准时间) * @aboutme q:282310962 wx:xy190310 */ 'use strict' import react, {component} from 'react' import { stylesheet, dimensions, pixelratio, touchablehighlight, modal, view, text, image, activityindicator, alert } from 'react-native' const pixel = pixelratio.get() const {width, height} = dimensions.get('window') export default class rnpop extends component{ /************************** * 弹窗配置参数 */ static defaultprops = { isvisible: false, //弹窗显示 id: 'rnpop', //弹窗id标识 title: '', //标题 content: '', //内容 style: null, //自定义弹窗样式 {object} contentstyle: null, //内容样式 skin: '', //自定义弹窗风格 icon: '', //自定义弹窗图标 shade: true, //遮罩层 shadeclose: true, //点击遮罩层关闭 opacity: '', //遮罩层透明度 xclose: false, //自定义关闭按钮 time: 0, //弹窗自动关闭秒数 xtime: false, //显示关闭秒数 anim: 'scalein', //弹窗动画 follow: null, //跟随定位(适用于在长按位置定位弹窗) position: '', //弹窗位置 zindex: 9999, //层叠等级 btns: null, //弹窗按钮(不设置则不显示按钮)[{...options}, {...options}] } constructor(props){ super(props) this.state = { ...this.props } this.timer = null } render(){ let opt = this.state // 自定义toast图标 let slotimg = { success: require('./skin/success.png'), error: require('./skin/error.png'), info: require('./skin/info.png'), } ... } /************************** * 显示弹窗事件(处理传参) */ show = (args) => { this.setstate({ ...this.props, ...args, isvisible: true }) } /************************** * 关闭弹窗事件 */ close = () => { console.log('关闭') this.setstate({ ...this.props }) this.timer && cleartimeout(this.timer) delete this.timer } }
◆ react-native自定义弹窗模板
<modal transparent={true} visible={opt.isvisible} onrequestclose={this.close}> <view style={styles.rnpop__ui_panel}> {/* 遮罩 */} { opt.shade && <view style={styles.rnpop__ui_mask} ontouchend={opt.shadeclose ? this.close : null} /> } {/* 窗体 */} <view style={styles.rnpop__ui_main}> <view style={styles.rnpop__ui_child}> {/* 标题 */} { opt.title ? <view style={[styles.rnpop__ui_tit]}><text style={[styles.rnpop__ui_titxt]}>{opt.title}</text></view> : null } {/* 内容 */} { opt.content ? <view style={[styles.rnpop__ui_cnt]}> ... <text style={[styles.rnpop__ui_cntxt, opt.contentstyle]}>{opt.content}</text> </view> : null } {/* 按钮 */} <view style={[styles.rnpop__ui_btnwrap]}> ... </view> </view> </view> </view> </modal>
◆ 附上之前的h5和小程序弹窗
h5手机端弹窗:
h5网页版弹窗:
小程序弹窗: