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