在开发 App 的时候,经常会使用到对话框(又叫消息框、提示框、告警框)。 在web开发中经常会用得到。今天就来介绍了一下react-native 封装弹出框
之前看到react-native-image-picker中自带了一个选择器,可以选择拍照还是图库,但我们的项目中有多处用到这个选择弹出框,所以就自己写了一下,最最重要的是ios和Android通用。先上动态效果图~
一、封装要点
2.通过一个boolean值控制组件的显示隐藏
3.弹框选项数组通过调用的js传到弹框组件
4.组件选项的字体颜色通过调用js传到组件,实现可拓展;
5.选择选项回调方法
二、代码实现
新建alertSelected.js
const [aWidth] = [width-20];
const [left,top] = [0,0];
const [middleLeft] = [(width - aWidth) / 2];
export default class AlertSelected extends Component {
constructor(props) {
super(props);
this.state = {
offset: new Animated.Value(0),opacity: new Animated.Value(0),title: "",choose0: "",choose1: "",hide: true,tipTextColor: '#333333',aHeight: 236,};
this.entityList = [];//数据源
this.callback = function () {
};//回调方法
}
render() {
if (this.state.hide) {
return (
} else {
return (
<Animated.View style={[{
width: aWidth,height: this.state.aHeight,left: middleLeft,...Platform.select({
ios:{
bottom: - 20,},}),alignItems: "center",justifyContent: "space-between",{
transform: [{
translateY: this.state.offset.interpolate({
inputRange: [0,1],outputRange: [height,(height - this.state.aHeight - 34)]
}),}]
}]}>
<View style={styles.content}>
<View style={styles.tipTitleView}>
<Text style={styles.tipTitleText}>{this.state.title}</Text>
</View>
{
this.entityList.map((item,i) => this.renderItem(item,i))
}
</View>
<TouchableHighlight
style={styles.button}
underlayColor={'#f0f0f0'}
onPress={this.cancel.bind(this)}
>
<Text style={styles.buttonText}>取消</Text>
</TouchableHighlight>
</Animated.View>
</View>
);
}
}
renderItem(item,i) {
return (
componentDidMount() {
}
componentWillUnmount() {
// 如果存在this.timer,则使用clearTimeout清空。
// 如果你使用多个timer,那么用多个变量,或者用个数组来保存引用,然后逐个clear
this.timer && clearTimeout(this.timer);
this.chooseTimer && clearTimeout(this.chooseTimer);
}
//显示动画
in() {
Animated.parallel([
Animated.timing(
this.state.opacity,{
easing: Easing.linear,//一个用于定义曲线的渐变函数
duration: 200,//动画持续的时间(单位是毫秒),默认为200。
toValue: 0.8,//动画的最终值
}
),Animated.timing(
this.state.offset,duration: 200,toValue: 1,}
)
]).start();
}
//隐藏动画
out() {
Animated.parallel([
Animated.timing(
this.state.opacity,toValue: 0,}
),}
)
]).start((finished) => this.setState({hide: true}));
}
//取消
cancel(event) {
if (!this.state.hide) {
this.out();
}
}
//选择
choose(i) {
if (!this.state.hide) {
this.out();
this.chooseTimer = setTimeout(()=>{
this.callback(i);
},200);
}
}
/**
-
titile: 标题
-
entityList:选择项数据 数组
-
tipTextColor: 字体颜色
-
callback:回调方法
*/
show(title: string,entityList: Array,tipTextColor: string,callback: Object) {
this.entityList = entityList;
this.callback = callback;if (this.state.hide) {
if (entityList && entityList.length > 0) {
let len = entityList.length;
if (len === 1) {
this.setState({title: title,choose0: entityList[0],hide: false,tipTextColor: tipTextColor,aHeight: 180},this.in);
} else if (len === 2) {
this.setState({title: title,choose1: entityList[1],aHeight: 236},this.in);
}
}
}
}
}
const styles = StyleSheet.create({
container: {
position: "absolute",width: width,height: height,left: left,top: top,mask: {
justifyContent: "center",backgroundColor: "#000000",opacity: 0.3,position: "absolute",// 提示标题
tipTitleView: {
height: 56,flexDirection: 'row',alignItems: 'center',justifyContent: 'center',backgroundColor: '#fff',marginLeft: 10,marginRight: 10
},// 提示文字
tipTitleText: {
color: "#999999",fontSize: 14,// 分割线
tipContentView: {
width: aWidth,height: 56,backgroundColor:'#fff',borderBottomLeftRadius: 5,borderBottomRightRadius: 5,item:{
width: aWidth,borderRadius: 5,button: {
height: 57,alignSelf: 'stretch',// 取消按钮
buttonText: {
fontSize: 17,color: "#0084ff",content: {
backgroundColor: '#fff',}
});
三、使用方法
新建demo.js
this.dialog.show("请选择照片",selectedArr,'#333333',this.callbackSelected);
}
// 回调
callbackSelected(i){
switch (i){
case 0: // 拍照
this.takePhoto();
break;
case 1: // 图库
this.pickMultiple();
break;
}
}
render() {
return (