使用 React Native 实现自定义 Dialog
CindiLeveri
8年前
<h2>前言</h2> <p>最近在项目中的RN模块遇到一个需求,弹出一个Dialog,但是原生的Alert满足不了需求,只能自己去写一个,最后决定使用Modal去实现,话不多说,介绍开始,效果图如下:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/d08401c00c8cb4a5001b778dc49dfead.png"></p> <h2>1.Modal介绍</h2> <pre> <code class="language-javascript">Modal视图在iOS原生开发中熟称:"模态视图",Modal进行封装之后,可以弹出来覆盖包含React Native跟视图的原生界面(例如:UiViewControllView,Activity)。在使用React Native开发的混合应用中使用Modal组件,该可以让你使用RN开发的内功呈现在原生视图的上面。 属性: 1.animationType enum('none', 'slide', 'fade') 动画类型 可选项为:none、slide、fade 2.onRequestClose function Android系统必须实现的方法 当modal隐藏时触发 3.onShow function 显示完回调方法 4.transparent bool 是否透明,默认不透明 5.visible bool modal状态,隐藏还是显示</code></pre> <h2>2.实现</h2> <pre> <code class="language-javascript">在此是将modal封装成为一个组件以便后续在别的地方引用。 组件ModalDialog.js代码如下</code></pre> <pre> <code class="language-javascript">/** * Created by peixuan.xie on 2017/2/28. */ import React, { Component } from 'react'; import { Modal, Text, TouchableHighlight, View , StyleSheet, BackAndroid } from 'react-native'; let Dimensions = require('Dimensions'); let SCREEN_WIDTH = Dimensions.get('window').width;//宽 let SCREEN_HEIGHT = Dimensions.get('window').height;//高 export default class ModalDialog extends Component { // 构造 constructor(props) { super(props); } static propTypes = { _dialogTitle: React.PropTypes.string, //标题 _dialogContent: React.PropTypes.string, //内容 _dialogLeftBtnTitle: React.PropTypes.string, //左按键标题 _dialogRightBtnTitle: React.PropTypes.string, //右按键标题 _dialogLeftBtnAction: React.PropTypes.func.isRequired, //左点击方法 _dialogRightBtnAction: React.PropTypes.func.isRequired, //右点击方法 _dialogVisible: React.PropTypes.bool, //显示还是隐藏 } static defaultProps = { _dialogTitle: '温馨提示', _dialogContent: '是否退出', _dialogLeftBtnTitle: '取消', _dialogRightBtnTitle: '确定', _dialogVisible: false, } render() { // onPress事件直接与父组件传递进来的属性挂接 return ( <Modal visible={this.props._dialogVisible} transparent={true} onRequestClose={() => {}} //如果是Android设备 必须有此方法 > <View style={styles.bg}> <View style={styles.dialog}> <View style={styles.dialogTitleView}> <Text style={styles.dialogTitle}> {this.props._dialogTitle} </Text> </View> <View style={styles.dialogContentView}> <Text style={styles.dialogContent}> {this.props._dialogContent} </Text> </View> <View style={styles.dialogBtnView}> <TouchableHighlight style={styles.dialogBtnViewItem} onPress={this.props._dialogLeftBtnAction}> <Text style={styles.leftButton}> {this.props._dialogLeftBtnTitle} </Text> </TouchableHighlight> <TouchableHighlight style={styles.dialogBtnViewItem} onPress={this.props._dialogRightBtnAction}> <Text style={styles.rightButton}> {this.props._dialogRightBtnTitle} </Text> </TouchableHighlight> </View> </View> </View> </Modal> ); } } const styles = StyleSheet.create({ bg: { //全屏显示 半透明 可以看到之前的控件但是不能操作了 width: SCREEN_WIDTH, height: SCREEN_HEIGHT, backgroundColor: 'rgba(52,52,52,0.5)', //rgba a0-1 其余都是16进制数 justifyContent: 'center', alignItems: 'center', }, dialog: { width: SCREEN_WIDTH * 0.8, height: SCREEN_HEIGHT * 0.28, backgroundColor: 'white', borderRadius: 8, }, dialogTitleView: { width: SCREEN_WIDTH * 0.8, height: SCREEN_HEIGHT * 0.08, justifyContent: 'center', alignItems: 'center', backgroundColor: '#EEEEEE', borderTopLeftRadius: 8, borderTopRightRadius: 8 }, dialogTitle: { textAlign: 'center', fontSize: 18, color: '#000000', }, dialogContentView: { width: SCREEN_WIDTH * 0.8, height: SCREEN_HEIGHT * 0.12, justifyContent: 'center', alignItems: 'center', }, dialogContent: { textAlign: 'center', fontSize: 16, color: '#4A4A4A', }, dialogBtnView: { width: SCREEN_WIDTH * 0.8, height: SCREEN_HEIGHT * 0.08, flexDirection: 'row', }, dialogBtnViewItem: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#E5F2FF', borderBottomLeftRadius: 8, borderBottomRightRadius: 8, }, leftButton: { fontSize: 18, color: '#007AFF', borderBottomLeftRadius: 8, }, rightButton: { fontSize: 18, color: '#007AFF', borderBottomRightRadius: 8, } });</code></pre> <p>调用代码如下:</p> <p>ModalDialog.js</p> <pre> <code class="language-javascript">/** * Created by peixuan.xie on 2017/2/28. */ import React,{Component} from 'react'; import { Modal, Text, TouchableOpacity, View, StyleSheet }from 'react-native'; import ModalDialog from '../component/ModalDialog.js' export default class ModalDemo extends Component { // 构造 constructor(props) { super(props); // 初始状态 this.state = { isDialogVisible: false }; } showDialog(){ this.setState({isDialogVisible:true}); } hideDialog(){ this.setState({isDialogVisible:false}); } render() { return ( <View style={styles.container}> <ModalDialog _dialogVisible={this.state.isDialogVisible} _dialogLeftBtnAction={()=> {this.hideDialog()}} _dialogRightBtnAction={()=>{this.hideDialog()}} /> <TouchableOpacity onPress={()=>this.showDialog()}> <Text style={styles.hello}>dialog</Text> </TouchableOpacity> </View> ); } } var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', }, hello: { fontSize: 20, margin: 10, textAlign:'left' }, });</code></pre> <p> </p> <p><strong>参考:</strong></p> <p>【1】 <a href="/misc/goto?guid=4959740581727351984" rel="nofollow,noindex">http://非死book.github.io/react-native/docs/modal.html</a></p> <p>【2】 <a href="/misc/goto?guid=4959740581829378831" rel="nofollow,noindex">http://reactnative.cn/docs/0.42/modal.html#content</a></p> <p>【3】 <a href="/misc/goto?guid=4959740581938568042" rel="nofollow,noindex">http://blog.csdn.net/jj120522/article/details/52051226</a></p> <p>【4】 <a href="http://www.open-open.com/lib/view/open1462870341406.html" rel="nofollow,noindex">http://www.open-open.com/lib/view/open1462870341406.html</a></p> <p> </p> <p>来自:http://blog.csdn.net/qq_27082837/article/details/60143572</p> <p> </p>