博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ReactNative实战系列 组件封装之Dialog(iOS和Android通用)
阅读量:4087 次
发布时间:2019-05-25

本文共 4255 字,大约阅读时间需要 14 分钟。

http://blog.csdn.net/column/details/reactnative2016.html?&page=1

最近在项目中封装了个Dialog组件,和平台上通用。

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

源码如下:

[javascript]   
 
  1. 'use strict';  
  2. import React, { Component } from 'react';  
  3. import {  
  4.   StyleSheet,  
  5.   View,  
  6.   Image,  
  7.   Text,  
  8.   TouchableHighlight,  
  9.   Animated,  
  10.   Easing,  
  11.   Dimensions,  
  12. } from 'react-native';  
  13.   
  14. import TimerMixin from 'react-timer-mixin';  
  15.   
  16. const {width, height} = Dimensions.get('window');  
  17. const navigatorH = 64; // navigator height  
  18. const [aWidth, aHeight] = [270, 108];  
  19. const [left, top] = [0, 0];  
  20. const [middleLeft, middleTop] = [(width - aWidth) / 2, (height - aHeight) / 2 - navigatorH];  
  21.   
  22. /** 
  23. * Dialog组件 
  24. * <Dialog ref="dialog" callback={this.callback.bind(this)}/> 
  25. * 调用show方法,调起组件   this.refs.dialog.show("确定删除吗"); 
  26. */  
  27.   
  28. export default class Dialog extends Component {  
  29.   mixins = [TimerMixin];  
  30.   parent ={};  
  31.   
  32.   
  33.   constructor(props) {  
  34.     super(props);  
  35.     this.state = {  
  36.       offset: new Animated.Value(0),  
  37.       opacity: new Animated.Value(0),  
  38.       title: "",  
  39.       hide: true,  
  40.     };  
  41.   }  
  42.   
  43.   render() {  
  44.     if(this.state.hide){  
  45.       return (<View />)  
  46.     } else {  
  47.       return (  
  48.         <View style={styles.container} >  
  49.           <Animated.View style={ styles.mask } >  
  50.           </Animated.View>  
  51.   
  52.           <Animated.View style={[styles.tip , {transform: [{  
  53.                 translateY: this.state.offset.interpolate({  
  54.                  inputRange: [0, 1,2],  
  55.                  outputRange: [0, middleTop,height]  
  56.                 }),  
  57.               }]  
  58.             }]}>  
  59.             <View style={styles.tipTitleView}>  
  60.               <Text style={styles.tipTitleText}>{
    this.state.title}</Text>  
  61.             </View>  
  62.   
  63.             <View style={styles.btnView}>  
  64.               <TouchableHighlight style={styles.cancelBtnView} underlayColor='#f0f0f0' onPress={
    this.cancelBtn.bind(this)}>  
  65.                 <Text style={styles.cancelBtnText}>取消</Text>  
  66.               </TouchableHighlight>  
  67.               <TouchableHighlight style={styles.okBtnView} underlayColor='#f0f0f0' onPress={
    this.okBtn.bind(this)}>  
  68.                 <Text style={styles.okBtnText}>确定</Text>  
  69.               </TouchableHighlight>  
  70.             </View>  
  71.           </Animated.View>  
  72.         </View>  
  73.       );  
  74.     }  
  75.   }  
  76.   
  77.   
  78.   //显示动画  
  79.   in() {  
  80.     Animated.parallel([  
  81.       Animated.timing(  
  82.         this.state.opacity,  
  83.         {  
  84.           easing: Easing.linear,  
  85.           duration: 500,  
  86.           toValue: 0.8,  
  87.         }  
  88.       ),  
  89.       Animated.timing(  
  90.         this.state.offset,  
  91.         {  
  92.           easing: Easing.linear,  
  93.           duration: 500,  
  94.           toValue: 1,  
  95.         }  
  96.       )  
  97.     ]).start();  
  98.   }  
  99.   
  100.   //隐藏动画  
  101.   out(){  
  102.     Animated.parallel([  
  103.       Animated.timing(  
  104.         this.state.opacity,  
  105.         {  
  106.           easing: Easing.linear,  
  107.           duration: 500,  
  108.           toValue: 0,  
  109.         }  
  110.       ),  
  111.       Animated.timing(  
  112.         this.state.offset,  
  113.         {  
  114.           easing: Easing.linear,  
  115.           duration: 500,  
  116.           toValue: 2,  
  117.         }  
  118.       )  
  119.     ]).start();  
  120.   
  121.     setTimeout(  
  122.       () => {  
  123.         this.setState({hide: true});  
  124.         //还原到顶部  
  125.         Animated.timing(  
  126.           this.state.offset,  
  127.           {  
  128.             easing: Easing.linear,  
  129.             duration: 500,  
  130.             toValue: 0,  
  131.           }  
  132.         ).start();  
  133.       },  
  134.       500  
  135.     );  
  136.   }  
  137.   
  138.   //取消  
  139.   cancelBtn(event) {  
  140.     if(!this.state.hide){  
  141.       this.out();  
  142.     }  
  143.   }  
  144.   
  145.   // doCallback(fn,args){
      
  146.   //   fn.apply(this.parent, args);  
  147.   // }  
  148.   
  149.   //选择  
  150.   okBtn() {  
  151.     if(!this.state.hide){  
  152.       this.out();  
  153.       setTimeout(  
  154.         () => {  
  155.           let {callback} = this.props;  
  156.           callback.apply(null,[]);  
  157.         },  
  158.         500  
  159.       );  
  160.     }  
  161.   }  
  162.   
  163.   /** 
  164.   * 弹出控件 
  165.   * titile: 标题 
  166.   */  
  167.   show(title: string) {  
  168.     if(this.state.hide){  
  169.       this.setState({title: title, hide: false}, this.in);  
  170.     }  
  171.   }  
  172. }  
  173.   
  174. const styles = StyleSheet.create({  
  175.   container: {  
  176.     position:"absolute",  
  177.     width:width,  
  178.     height:height,  
  179.     left:left,  
  180.     top:top,  
  181.   },  
  182.   mask: {  
  183.     justifyContent:"center",  
  184.     backgroundColor:"#383838",  
  185.     opacity:0.8,  
  186.     position:"absolute",  
  187.     width:width,  
  188.     height:height,  
  189.     left:left,  
  190.     top:top,  
  191.   },  
  192.   tip: {  
  193.     width:aWidth,  
  194.     height:aHeight,  
  195.     left:middleLeft,  
  196.     backgroundColor:"#fff",  
  197.     alignItems:"center",  
  198.     justifyContent:"space-between",  
  199.   },  
  200.   tipTitleView: {  
  201.     width:aWidth,  
  202.     flexDirection:'row',  
  203.     alignItems:'center',  
  204.     justifyContent:'center',  
  205.     borderBottomWidth:1/2,  
  206.     borderColor:'#f0f0f0',  
  207.   },  
  208.   tipTitleText:{  
  209.     color:"#333333",  
  210.     fontSize:17,  
  211.     marginTop:28,  
  212.     marginBottom:19,  
  213.     textAlignVertical:'center',  
  214.     textAlign:'center',  
  215.   },  
  216.   
  217.   btnView:{  
  218.     flexDirection:'row',  
  219.     height: 44,  
  220.   },  
  221.   cancelBtnView:{  
  222.     width:aWidth/2,  
  223.     height: 44,  
  224.     backgroundColor: '#fff',  
  225.     alignItems: 'center',  
  226.     justifyContent: 'center',  
  227.     borderRightWidth:1/2,  
  228.     borderColor:'#f0f0f0',  
  229.   },  
  230.   cancelBtnText: {  
  231.     fontSize:17,  
  232.     color:"#e6454a",  
  233.     textAlign:"center",  
  234.     fontWeight:'bold',  
  235.   },  
  236.   okBtnView:{  
  237.     width:aWidth/2,  
  238.     height: 44,  
  239.     backgroundColor: '#fff',  
  240.     alignItems: 'center',  
  241.     justifyContent: 'center',  
  242.   },  
  243.   okBtnText: {  
  244.     fontSize:17,  
  245.     color:"#e6454a",  
  246.     textAlign:"center",  
  247.   },  
  248.   
  249. });  

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

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

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

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

3、调用show方法

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

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

组件效果如下:

你可能感兴趣的文章
React+Redux系列教程
查看>>
react-native 自定义倒计时按钮
查看>>
19 个 JavaScript 常用的简写技术
查看>>
ES6这些就够了
查看>>
微信小程序:支付系列专辑(开发指南+精品Demo)
查看>>
iOS应用间相互跳转
查看>>
iOS开发之支付宝集成
查看>>
iOS开发 支付之银联支付集成
查看>>
iOS开发支付集成之微信支付
查看>>
浅谈JavaScript--声明提升
查看>>
React非嵌套组件通信
查看>>
Websocket 使用指南
查看>>
浏览器兼容性问题解决方案 · 总结
查看>>
一个很棒的Flutter学习资源列表
查看>>
为什么你应该放弃React老的Context API用新的Context API
查看>>
Flutter 布局控件完结篇
查看>>
Koa2初体验
查看>>
Koa 2 初体验(二)
查看>>
Koa2框架原理解析和实现
查看>>
vue源码系列文章good
查看>>