上一篇文章介绍React Native系统提供的两个弹出框的api——Alert与AlertIOS,Alert可以在双平台通用,但是只能展示信息量有限功能单一的文本对话框。AlertIOS比Alert稍微丰富一点,可以展示供用户输入的对话框,但只能在iOS中使用。但是如果我们想在Android平台实现带输入框的提示框呢?或者有需求要定制功能更复杂的对话框,如带多选项的对话框?这时我们可以通过调用原生平台api来实现自己的需求。不过这里幸好React Native提供一个组件——Modal 可以让我们很方便的实现对话框的效果。本文将介绍通过Modal实现自定义弹出对话框。
Modal组件可以用来覆盖包含React Native根视图的原生视图(如UIViewController,Activity)。在嵌入React Native的混合应用中可以使用Modal,可以使应用中用RN开发的那部分内容覆盖在原生视图上显示。
属性 | 类型 | 描述 |
---|---|---|
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>TitleText>
<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 .自定义布局
"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即可控制其关闭。
"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调用原生模块。