/*
* @Date: 2019-08-30 16:05:37
* @Description: 真的不想每次都寫個Modal了。
* @Author: zhangji
* @LastEditors: ZhangJi
* @LastEditTime: 2019-09-02 11:16:51
*/
import React from "react";
import _ from "lodash";
import {
View,
StyleSheet,
Component,
Platform,
ActivityIndicator,
FlatList,
Image,
TouchableWithoutFeedback,
TouchableOpacity,
Text,
Alert,
Modal,
RefreshControl,
NativeModules,
ScrollView,
TekLoadingDialog,
LayoutAnimation
} = 'react-native';
/**
* 通用彈出框,包括居中彈出框和底部彈出框
* @param {Boolean} isVisible 控制是否可見
* @param {?Boolean} isBottomView 可選,控制是否爲底部彈出框樣式,默認爲居中彈出框
* @param {?Boolean} isTouchMaskToClose 可選,控制是否點擊陰影關閉彈窗,默認開啓
* @param {?String} title 可選,標題,默認爲`提示`,只對居中彈窗生效
* @param {?String} confirmText 可選,居中框的確認按鈕描述,默認爲`確 認`
* @param {?JSX} customTitleView 可選,自定義title樣式(包括居中和底部彈框),若該屬性有值,會覆蓋默認樣式,當需要自定義按鈕點擊功能時可以用這個,
* @param {?JSX} customBottomView 可選,自定義底部樣式(包括居中和底部彈框),若該屬性有值,會覆蓋默認樣式,當需要自定義按鈕點擊功能時可以用這個,
*
* eg:` <MyModal
* isVisible={this.state.isVisible}
* >
* <Text>測試彈窗</Text>
* </MyModal>`
*/
export default class MyModal extends Component {
constructor(props) {
super(props);
this.title = props.title || "提示";
this.confirmText = props.confirmText || "確 認";
this.customTitleView = props.customTitleView
? props.customTitleView
: false;
this.customBottomView = props.customBottomView
? props.customBottomView
: false;
this.isBottomView = !!JSON.stringify(props.isBottomView)
? this.props.isBottomView
: false;
this.isTouchMaskToClose = !!JSON.stringify(props.isTouchMaskToClose)
? this.props.isTouchMaskToClose
: true;
this.state = {
isVisible: this.props.isVisible || false
};
}
setModalVisiable(state) {
this.setState({
isVisible: state
});
}
componentWillReceiveProps(newProps) {
if (!_.isEmpty(this.props, newProps)) {
if (this.state.isVisible != newProps.isVisible) {
this.setState({
isVisible: newProps.isVisible
});
}
}
}
render() {
return (
<Modal
animationType="fade"
transparent={true}
visible={this.state.isVisible}
onRequestClose={() => {
this.setModalVisiable(false);
}}
>
{this.isBottomView ? (
<View style={styles.bottomModalContainer}>
<TouchableOpacity
style={styles.bottomMask}
onPress={() => {
this.setModalVisiable(false);
}}
/>
<View style={styles.bottomContent}>{this.props.children}</View>
{this.customBottomView ? (
this.customBottomView
) : (
<View style={styles.bottomBtns}>
<TouchableOpacity
onPress={() => {
this.setModalVisiable(false);
}}
>
<View
style={[
styles.bottomBtnsView,
{ borderWidth: 0.5, borderColor: "#999" }
]}
>
<Text
style={[
styles.bottomBtnsText,
{ color: "#333", fontFamily: "PingFangSC-Light" }
]}
>
取消
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => {}}>
<View
style={[
styles.bottomBtnsView,
{
backgroundColor: "#417EFF",
borderWidth: 0.5,
borderColor: "#417EFF"
}
]}
>
<Text
style={[
styles.bottomBtnsText,
{ color: "#fff", fontWeight: "bold" }
]}
>
確定
</Text>
</View>
</TouchableOpacity>
</View>
)}
</View>
) : (
<View style={styles.modalContainer}>
<TouchableWithoutFeedback
onPress={() => {
this.isTouchMaskToClose ? this.setModalVisiable(false) : null;
}}
>
<View style={styles.mask} />
</TouchableWithoutFeedback>
<View style={styles.container}>
{this.customTitleView ? (
this.customTitleView
) : (
<Text style={styles.title}>{this.title}</Text>
)}
{this.props.children}
<View
style={{
height: 0.5,
width: appConfig.ScreenWidth - 42,
backgroundColor: "#E5E5E5"
}}
/>
{this.customBottomView ? (
this.customBottomView
) : (
<TouchableOpacity onPress={() => this.setModalVisiable(false)}>
<Text style={styles.confirmBtn}>{this.confirmText}</Text>
</TouchableOpacity>
)}
</View>
</View>
)}
</Modal>
);
}
}
const styles = StyleSheet.create({
modalContainer: {
flex: 1,
justifyContent: "center",
alignItems: "center",
width: appConfig.ScreenWidth,
height: appConfig.ScreenHeight
},
mask: {
width: appConfig.ScreenWidth,
height: appConfig.ScreenHeight,
backgroundColor: "rgba(0,0,0,.4)",
position: "absolute",
left: 0,
top: 0
},
container: {
width: appConfig.ScreenWidth - 30,
backgroundColor: "#FFF",
borderTopLeftRadius: 9,
borderTopRightRadius: 9,
borderBottomLeftRadius: 9,
borderBottomRightRadius: 9,
justifyContent: "center",
alignItems: "center"
},
title: {
textAlign: "center",
fontFamily: "PingFangSC-Semibold",
fontSize: 16,
color: "#333",
marginTop: 18
},
confirmBtn: {
color: "#417EFF",
fontSize: 17,
fontFamily: "PingFangSC-Semibold",
marginBottom: 18,
marginTop: 14.2,
width: appConfig.ScreenWidth - 42,
textAlign: "center"
},
bottomModalContainer: {
flex: 1,
justifyContent: "flex-end",
width: appConfig.ScreenWidth,
height: appConfig.ScreenHeight
},
bottomMask: {
flex: 1,
width: appConfig.ScreenWidth,
marginBottom: -9,
backgroundColor: "rgba(0,0,0,.4)"
},
content: {
width: appConfig.ScreenWidth,
backgroundColor: "#FFF",
borderTopLeftRadius: 9,
borderTopRightRadius: 9,
paddingTop: 15
},
bottomBtns: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-around",
backgroundColor: "#fff",
marginBottom: appConfig.StatusBarHeight == 44 ? 34 : 0,
shadowColor: "#00000033",
shadowOffset: { width: 0, height: -9 },
shadowOpacity: 0.1,
shadowRadius: 6,
elevation: 10
},
bottomBtnsView: {
width: 165,
height: 42,
borderRadius: 100,
marginTop: 12,
marginBottom: 12,
justifyContent: "center",
alignItems: "center"
},
bottomBtnsText: {
fontSize: 16
},
bottomModalContainer: {
flex: 1,
justifyContent: "flex-end",
width: appConfig.ScreenWidth,
height: appConfig.ScreenHeight
},
bottomMask: {
flex: 1,
width: appConfig.ScreenWidth,
backgroundColor: "#33333344",
marginBottom: -9
},
bottomContent: {
width: appConfig.ScreenWidth,
backgroundColor: "#FFF",
borderTopLeftRadius: 9,
borderTopRightRadius: 9,
paddingTop: 15
}
});
ReactNative封裝的優雅居中/底部彈出框
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.