使用React Native 實現自定義Dialog
阿新 • • 發佈:2019-02-05
前言
最近在專案中的RN模組遇到一個需求,彈出一個Dialog,但是原生的Alert滿足不了需求,只能自己去寫一個,最後決定使用Modal去實現,話不多說,介紹開始,效果圖如下:
1.Modal介紹
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狀態,隱藏還是顯示
2.實現
在此是將modal封裝成為一個元件以便後續在別的地方引用。
元件ModalDialog.js程式碼如下
/**
* 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,
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
呼叫程式碼如下:
ModalDialog.js
/**
* 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'
},
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61