1. 程式人生 > >react native學習筆記24——Modal實現自定義彈出對話方塊

react native學習筆記24——Modal實現自定義彈出對話方塊

前言

上一篇文章介紹React Native系統提供的兩個彈出框的api——Alert與AlertIOS,Alert可以在雙平臺通用,但是隻能展示資訊量有限功能單一的文字對話方塊。AlertIOS比Alert稍微豐富一點,可以展示供使用者輸入的對話方塊,但只能在iOS中使用。但是如果我們想在Android平臺實現帶輸入框的提示框呢?或者有需求要定製功能更復雜的對話方塊,如帶多選項的對話方塊?這時我們可以通過呼叫原生平臺api來實現自己的需求。不過這裡幸好React Native提供一個元件——Modal 可以讓我們很方便的實現對話方塊的效果。本文將介紹通過Modal實現自定義彈出對話方塊。

Modal元件可以用來覆蓋包含React Native根檢視的原生檢視(如UIViewController,Activity)。在嵌入React Native的混合應用中可以使用Modal,可以使應用中用RN開發的那部分內容覆蓋在原生檢視上顯示。

Modal的屬性方法

屬性 型別 描述
animationType enum(‘none’, ‘slide’, ‘fade’) 動畫效果型別
transparent bool 控制是否透明
visible bool 控制是否顯示
onShow function Modal顯示時呼叫該方法
onRequestClose function Modal被銷燬時呼叫該方法
onOrientationChange(iOS) function 方向改變時呼叫
supportedOrientations(iOS) function 允許Modal旋轉到任何指定取向,其值為‘portrait’, ‘portrait-upside-down’, ‘landscape’,’landscape-left’,’landscape-right’

在Android平臺onRequestClose是必要方法,用於處理物理返回鍵的響應。
在iOS平臺supportedOrientations

仍然受info.plist 中的 UISupportedInterfaceOrientations欄位所指定的限制。

使用例項

下例通過Modal實現了自定義的帶輸入框的彈出框,在android和ios兩個平臺上均可使用。

import React, { Component } from 'react';
import {
    Modal,
    Text,
    TouchableHighlight,
    TouchableOpacity,
    View ,
    StyleSheet,
    Image,
    TextInput} from 'react-native';
let Dimensions = require('Dimensions');
let screenWidth = Dimensions.get('window').width;
let dialogWidth = screenWidth-80;
export default class ModalExample extends Component {

    constructor(props) {
        super(props);
        this.state = {modalVisible: false};
    }

    setModalVisible(visible) {
        this.setState({modalVisible: visible});
    }
    onClose() {
        this.setState({modalVisible: false});
    }
    render() {
        return (
            <View style={{marginTop: 22}}>
                <Modal
                    animationType={"slide"}
                    transparent={true}
                    visible={this.state.modalVisible}
                    onRequestClose={() => {this.setModalVisible(false)}}
                >
                    <TouchableOpacity style={{flex:1}} onPress={this.onClose.bind(this)}>
                    <View style={styles.container}>
                        <View style={styles.innerContainer}>
                            <Text>Title</Text>
                            <TextInput
                                style={styles.inputtext}
                                placeholder="Type here!"
                            />
                            <View style={styles.btnContainer}>
                                <TouchableHighlight onPress={() => {
                                    this.setModalVisible(!this.state.modalVisible)
                                }}>
                                    <Text  style={styles.hidemodalTxt}>關閉</Text>
                                </TouchableHighlight>
                            </View>
                        </View>
                    </View>
                    </TouchableOpacity>
                </Modal>

                <TouchableHighlight onPress={() => {
                    this.setModalVisible(true)
                }}>
                    <Text>彈出對話方塊</Text>
                </TouchableHighlight>

            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        padding: 40,
        backgroundColor: 'rgba(0, 0, 0, 0.5)'
    },
    innerContainer: {
        borderRadius: 10,
        alignItems: 'center',
        backgroundColor: '#fff',
        padding: 20

    },
    btnContainer:{
        width:dialogWidth,
        borderTopWidth:1,
        borderTopColor:'#777',
        alignItems:'center'
    },
    inputtext:{
        width:dialogWidth-20,
        margin:10,
    },
    hidemodalTxt: {
        marginTop:10,
    },
});

效果如下:

從上例可以看出Modal的使用方法很簡單,以下是其在使用過程中比較關鍵的三個點。

1 .自定義佈局

       <Modal  
              animationType={"slide"}
              transparent={true}
              visible={this.state.modalVisible}
              onRequestClose={() => {this.setModalVisible(false)}}>
            ...
       </Modal>

在省略的地方可根據你的需求實現任意自定義佈局。這裡需要注意的是, Modal 是覆蓋整個螢幕的,形成半透明遮罩狀態的效果需要在最外層上面設定其背景為半透明:

 backgroundColor: 'rgba(0, 0, 0, 0.5)'

2 .點選空白處關閉
如果要實現點選空白處關閉對話方塊的效果可以在Modal的最外層加上觸屏事件的監聽,修改Modal的visible屬性為false即可控制其關閉。

    <Modal
          animationType={"slide"}
          transparent={true}
          visible={this.state.modalVisible}
          onRequestClose={() => {this.setModalVisible(false)}}
          >
         <TouchableOpacity style={{flex:1}} onPress={this.onClose.bind(this)}>
          ...
         </TouchableOpacity>
    </Modal>
...
 onClose() {
        this.setState({modalVisible: false});
 }

3 .android手機按物理返回鍵關閉Modal,
在onRequestClose方法中通過修改Modal的visible屬性為false即可控制其關閉。具體實現同2。

結語

通過Modal實現自定義對話方塊可同時適配Android、iOS雙平臺。在最開始我提到過實現自定義對話方塊還有另一種方法——通過呼叫原生平臺api。對於某些功能可能React Native還沒有相應的模組包裝,這時我們通常的做法就是通過呼叫原生元件,然後經過特定的封裝來達到效果,下一節將介紹如何使用React Native呼叫原生模組。