您的位置:首页 > Web前端 > React

《React-Native系列》13、 组件封装之Dialog(iOS和Android通用)

2016-08-13 22:31 866 查看
最近在项目中封装了个Dialog组件,iOS和Android平台上通用。

组件Dialog显示时,从页面顶部滑动到中间,点击确认或取消后,从页面底部划出页面,需要注意动画的实现。

源码如下:

'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
View,
Image,
Text,
TouchableHighlight,
Animated,
Easing,
Dimensions,
} from 'react-native';

import TimerMixin from 'react-timer-mixin';

const {width, height} = Dimensions.get('window');
const navigatorH = 64; // navigator height
const [aWidth, aHeight] = [270, 108];
const [left, top] = [0, 0];
const [middleLeft, middleTop] = [(width - aWidth) / 2, (height - aHeight) / 2 - navigatorH];

/**
* Dialog组件
* <Dialog ref="dialog" callback={this.callback.bind(this)}/>
* 调用show方法,调起组件   this.refs.dialog.show("确定删除吗");
*/

export default class Dialog extends Component {
mixins = [TimerMixin];
parent ={};

constructor(props) {
super(props);
this.state = {
offset: new Animated.Value(0),
opacity: new Animated.Value(0),
title: "",
hide: true,
};
}

render() {
if(this.state.hide){
return (<View />)
} else {
return (
<View style={styles.container} >
<Animated.View style={ styles.mask } >
</Animated.View>

<Animated.View style={[styles.tip , {transform: [{
translateY: this.state.offset.interpolate({
inputRange: [0, 1,2],
outputRange: [0, middleTop,height]
}),
}]
}]}>
<View style={styles.tipTitleView}>
<Text style={styles.tipTitleText}>{this.state.title}</Text>
</View>

<View style={styles.btnView}>
<TouchableHighlight style={styles.cancelBtnView} underlayColor='#f0f0f0' onPress={this.cancelBtn.bind(this)}>
<Text style={styles.cancelBtnText}>取消</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.okBtnView} underlayColor='#f0f0f0' onPress={this.okBtn.bind(this)}>
<Text style={styles.okBtnText}>确定</Text>
</TouchableHighlight>
</View>
</Animated.View>
</View>
);
}
}

//显示动画
in() {
Animated.parallel([
Animated.timing(
this.state.opacity,
{
easing: Easing.linear,
duration: 500,
toValue: 0.8,
}
),
Animated.timing(
this.state.offset,
{
easing: Easing.linear,
duration: 500,
toValue: 1,
}
)
]).start();
}

//隐藏动画
out(){
Animated.parallel([
Animated.timing(
this.state.opacity,
{
easing: Easing.linear,
duration: 500,
toValue: 0,
}
),
Animated.timing(
this.state.offset,
{
easing: Easing.linear,
duration: 500,
toValue: 2,
}
)
]).start();

setTimeout(
() => {
this.setState({hide: true});
//还原到顶部
Animated.timing(
this.state.offset,
{
easing: Easing.linear,
duration: 500,
toValue: 0,
}
).start();
},
500
);
}

//取消
cancelBtn(event) {
if(!this.state.hide){
this.out();
}
}

// doCallback(fn,args){
//   fn.apply(this.parent, args);
// }

//选择
okBtn() {
if(!this.state.hide){
this.out();
setTimeout(
() => {
let {callback} = this.props;
callback.apply(null,[]);
},
500
);
}
}

/**
* 弹出控件
* titile: 标题
*/
show(title: string) {
if(this.state.hide){
this.setState({title: title, hide: false}, this.in);
}
}
}

const styles = StyleSheet.create({
container: {
position:"absolute",
width:width,
height:height,
left:left,
top:top,
},
mask: {
justifyContent:"center",
backgroundColor:"#383838",
opacity:0.8,
position:"absolute",
width:width,
height:height,
left:left,
top:top,
},
tip: {
width:aWidth,
height:aHeight,
left:middleLeft,
backgroundColor:"#fff",
alignItems:"center",
justifyContent:"space-between",
},
tipTitleView: {
width:aWidth,
flexDirection:'row',
alignItems:'center',
justifyContent:'center',
borderBottomWidth:1/2,
borderColor:'#f0f0f0',
},
tipTitleText:{
color:"#333333",
fontSize:17,
marginTop:28,
marginBottom:19,
textAlignVertical:'center',
textAlign:'center',
},

btnView:{
flexDirection:'row',
height: 44,
},
cancelBtnView:{
width:aWidth/2,
height: 44,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
borderRightWidth:1/2,
borderColor:'#f0f0f0',
},
cancelBtnText: {
fontSize:17,
color:"#e6454a",
textAlign:"center",
fontWeight:'bold',
},
okBtnView:{
width:aWidth/2,
height: 44,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
okBtnText: {
fontSize:17,
color:"#e6454a",
textAlign:"center",
},

});


如果需要使用该组件,只需要3步即可:

1、在你的页面import 组件,加入代码:

<Dialog ref="dialog" callback={this.callback.bind(this)}/>


2、自定义回调方法callback,处理选中逻辑

3、调用show方法

调用show方法,调起组件   this.refs.dialog.show("确定要取消订单吗");


备注:组件的样式可以根据你的需求修改,组件的动画也可以修改。

组件效果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ReactNative
相关文章推荐