用react-native写项目也有段时间了,一直没有看好自定义程度多高的自定义弹窗组件、
之前写了很长时间的iOS原生、一直觉得MMPopupView这个组件非常好用,当然还有一些其他的swift库,这个不是今天的重点,下次有空在介绍了。
先来看看效果
并且是纯js版本、不需要分别对安卓和iOS做任何类似react-native link的处理
import React, {
Component,
} from 'react';
import {
Animated,
Easing,
View,
Text,
StyleSheet,
Dimensions,
TouchableOpacity
} from 'react-native';
import PropTypes from 'prop-types';
const AnimatedTouchableOpacity = Animated.createAnimatedComponent(TouchableOpacity)
let element = null;
const screen_width = Dimensions.get("window").width;
const screen_height = Dimensions.get("window").height;
const marginHor = 50;
const animationDuration = 500
export default class PopupWindow extends Component {
constructor(props) {
super(props);
this.state = {
aniColor: new Animated.Value(0),
aniScale: new Animated.Value(0),
visible: false,
};
this.animationOpacity = Animated.timing(this.state.aniColor, {
toValue: 0.5,
duration: animationDuration,
});
this.animationScale = Animated.spring(this.state.aniScale, {
toValue: 1,
duration: animationDuration,
bounciness: 10,
speed: 20
});
this.animationGroup = Animated.parallel([this.animationOpacity, this.animationScale]);
}
showCallBack = (finished) => {
console.log("动画显示完毕回调");
}
hideCallBack = (finished) => {
console.log("动画移除完毕回调");
}
/**
* 显示弹窗
* @param {显示完成回调} showCallBack
*/
show(showCallBack = this.showCallBack) {
this.setState({ visible: true })
this.showAnimation(showCallBack);
}
showAnimation(showCallBack = (result) => { }) {
this.animationGroup.start(showCallBack);
}
/**
* 隐藏弹窗
*/
hide() {
this.setState({ visible: false })
this.hideAnimation();
}
hideAnimation() {
this.animationGroup.reset();
}
render() {
let { children, marginHorizontal = marginHor, touchUpDismiss = false, onTouchUpMask, maskColor = "rgba(23,25,25,0.5)" } = this.props;
if (!this.state.visible) {
return ;
}
return (
{
console.log("window popup click")
if (onTouchUpMask != 'undefined' && onTouchUpMask != null) {
onTouchUpMask();
debugger
return;
}
if (touchUpDismiss) {
this.hide()
}
}}
>
{this.renderChildrenComponents()}
)
}
/**
* 子类复写这个方法 可以定义
*/
renderChildrenComponents() {
return this.props.children;
}
}
//参数传递
PopupWindow.propTypes = {
maskColor: PropTypes.string,
marginHorizontal: PropTypes.number,
touchUpDismiss: PropTypes.bool,
onTouchUpMask: PropTypes.func,
}
const styles = StyleSheet.create({
window: {
position: 'absolute',
top: 0,
left: 0,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
justifyContent: "center",
alignItems: "center",
},
container: {
flexDirection: "column",
width: screen_width - marginHor * 2,
marginHorizontal: marginHor,
justifyContent: "space-between",
alignItems: "center"
}
})
import React, {
Component,
} from 'react';
import {
Animated,
Easing,
View,
Text,
StyleSheet,
Dimensions,
TouchableOpacity
} from 'react-native';
import PropTypes from 'prop-types';
import PopupWindow from './Popup';
export default class LWAlertComponent extends PopupWindow {
constructor(props) {
super(props)
this.state = {
...this.state,
}
}
renderChildrenComponents() {
console.log("renderChildrenComponents --- " + "LWAlertComponent");
return (
title
confirm dialog --- content content content content content content content
{
this.hide()
}}
>
OK
)
}
}
const model = StyleSheet.create({
container: {
justifyContent: "space-between",
alignItems: "stretch",
alignSelf: "stretch",
backgroundColor: "white",
borderRadius: 5,
},
title: {
fontSize: 17,
color: "black",
fontWeight: "500",
marginVertical: 15,
textAlign: "center"
},
content: {
fontSize: 17,
color: "gray",
marginBottom: 20,
paddingHorizontal: 20,
textAlign: "center"
},
bt_confirm: {
justifyContent: "center",
alignItems: "center",
height: 50,
},
text_confirm: {
color: "red",
fontWeight: "800",
fontSize: 18,
},
seperator_line: {
backgroundColor: "#ccc",
height: 0.5
}
})
showAnimation() {
console.log(this.pop);
this.refs.pop.show()
}
render() {
return
show alert
{/*
Destroy element
Update element
*/}
{
console.log('onTouchUpMask');
this.refs.pop.hide();
}}
>
;
}
LWAlertComponent 这个组件就是经过封装的自定义组件、上面是使用方法
github 地址