react-native自定義Modal模態框|仿ios、微信彈窗RN版

前序

縱觀每一個優質項目,不管web端仍是native原生應用開發,彈窗都是不可忽視的一環,能很大程度上直接決定用戶體驗。如:微信、支付寶、ios都有很成熟的一套彈窗UI展現場景。html

最近一直沉迷在react-native開發研究中,學習起來發現沒有想象的難,不過也採坑了很多。鑑於以前有基於h5和小程序技術開發過自定義彈窗的經驗,就想着用react-native技術實現msg信息框|alert提示框|confirm確認框|toast弱提示/loading|仿ios、android彈窗,就有了這個rnPop彈窗組件RN版。react

效果圖

仿真模擬器上畫質有些次,真機實測完美,可忽略這一點android

看了上圖,是否是以爲調用方式還挺多的,沒錯,很豐富的應用場景ios

◆ rnPop彈窗組件目錄結構web

◆ 引入方式及調用小程序

import RNPop from '../utils/rnPop/rnPop.js'react-native

顯示: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自定義彈窗模板ide

<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手機端彈窗:http://www.javashuo.com/article/p-nbhuwpsg-cg.html

h5網頁版彈窗:http://www.javashuo.com/article/p-fagipdfc-h.html

小程序彈窗:http://www.javashuo.com/article/p-exlmycvb-cw.html

相關文章
相關標籤/搜索