react-native 封装选择弹出框示例(试用ios&android)


Posted in Javascript onJuly 11, 2017

在开发 App 的时候,经常会使用到对话框(又叫消息框、提示框、告警框)。 在web开发中经常会用得到。今天就来介绍了一下react-native 封装弹出框

之前看到react-native-image-picker中自带了一个选择器,可以选择拍照还是图库,但我们的项目中有多处用到这个选择弹出框,所以就自己写了一下,最最重要的是ios和Android通用。先上动态效果图~

react-native 封装选择弹出框示例(试用ios&android)

一、封装要点

1.使用动画实现弹框布局及显示隐藏效果

2.通过一个boolean值控制组件的显示隐藏

3.弹框选项数组通过调用的js传到弹框组件

4.组件选项的字体颜色通过调用js传到组件,实现可拓展;

5.选择选项回调方法

二、代码实现

新建alertSelected.js

/**
 * Created by sybil052 on 2017/6/19.
 */
import React, {Component} from 'react';
import {
  StyleSheet,
  View,
  Image,
  Text,
  TouchableHighlight,
  Animated,
  Easing,
  Dimensions,
  Platform,
  TouchableOpacity
} from 'react-native';

const {width, height} = Dimensions.get('window');
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 (<View />)
    } else {
      return (
        <View style={styles.container}>
          <Animated.View style={styles.mask}>
          </Animated.View>

          <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 (
      <View style={styles.tipContentView}>
        <View style={{height: 0.5, backgroundColor: '#a9a9a9', width: aWidth}}/>
        <TouchableOpacity
        key={i}
        onPress={this.choose.bind(this, i)}
      >
          <View style={styles.item}>
            <Text style={{
              color: this.state.tipTextColor,
              fontSize: 17,
              textAlign: "center",
            }}>{item}</Text>
          </View>
        </TouchableOpacity>
      </View>
    );
  }

  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,
        {
          easing: Easing.linear,
          duration: 200,
          toValue: 1,
        }
      )
    ]).start();
 }

  //隐藏动画
  out() {
    Animated.parallel([
      Animated.timing(
        this.state.opacity,
        {
          easing: Easing.linear,
          duration: 200,
          toValue: 0,
        }
      ),
      Animated.timing(
        this.state.offset,
        {
          easing: Easing.linear,
          duration: 200,
          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);
    }
  }

 /**
 * 弹出控件,最多支持3个选项(包括取消)
 * 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, choose0: entityList[0], choose1: entityList[1], hide: false, tipTextColor: tipTextColor, 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",
    width: width,
    height: height,
    left: left,
    top: top,
  },
  // 提示标题
  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,
    height: 56,
    backgroundColor:'#fff',
    justifyContent: 'center',
    borderRadius: 5,
  },
  button: {
    height: 57,
    backgroundColor: '#fff',
    alignSelf: 'stretch',
    justifyContent: 'center',
    borderRadius: 5,
  },
  // 取消按钮
  buttonText: {
    fontSize: 17,
    color: "#0084ff",
    textAlign: "center",
  },
  content: {
    backgroundColor: '#fff',
    borderRadius: 5,
  }
});

三、使用方法

新建demo.js

const selectedArr = ["拍照", "图库"];
class Demo extends Component {
  constructor(props) {
    super(props);
    this.showAlertSelected = this.showAlertSelected.bind(this);
    this.callbackSelected = this.callbackSelected.bind(this);
  }

  showAlertSelected(){
    this.dialog.show("请选择照片", selectedArr, '#333333', this.callbackSelected);
  }
  // 回调
  callbackSelected(i){
    switch (i){
      case 0: // 拍照
        this.takePhoto();
        break;
      case 1: // 图库
        this.pickMultiple();
        break;
    }
  }
  render() {
    return (
      <View style={stylesCommon.container}>
        <TouchableOpacity onPress={() => {this.showAlertSelected();}}>
          <View style={styles.imageBorder}>
            <Text style={styles.photoText}>?</Text>
          </View>
        </TouchableOpacity>
        <DialogSelected ref={(dialog)=>{
          this.dialog = dialog;
        }} /> 
      </View>
    );
  } 
}

再来一张其他界面调用该组件的效果图~

react-native 封装选择弹出框示例(试用ios&amp;android)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js 创建快捷方式的代码(fso)
Nov 19 Javascript
使用Java实现简单的server/client回显功能的方法介绍
May 03 Javascript
jquery中文乱码的多种解决方法
Jun 21 Javascript
Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
Nov 14 Javascript
jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别
Dec 02 Javascript
node.js中的fs.open方法使用说明
Dec 17 Javascript
JavaScript中的some()方法使用详解
Jun 09 Javascript
javascript实现添加附件功能的方法
Nov 18 Javascript
如何提高数据访问速度
Dec 26 Javascript
微信小程序 两种为对象属性赋值的方式详解
Feb 23 Javascript
JS实现点击按钮可实现编辑功能
Jul 03 Javascript
在vue项目中promise解决回调地狱和并发请求的问题
Nov 09 Javascript
vue.js内部自定义指令与全局自定义指令的实现详解(利用directive)
Jul 11 #Javascript
javascript 玩转Date对象(实例讲解)
Jul 11 #Javascript
使用jQuery实现动态添加小广告
Jul 11 #jQuery
Vue中父组件向子组件通信的方法
Jul 11 #Javascript
实例讲解DataTables固定表格宽度(设置横向滚动条)
Jul 11 #Javascript
网页中的图片查看器viewjs使用方法
Jul 11 #Javascript
自定义事件解决重复请求BUG的问题
Jul 11 #Javascript
You might like
hessian 在PHP中的使用介绍
2010/12/13 PHP
php dirname(__FILE__) 获取当前文件的绝对路径
2011/06/28 PHP
PHP防盗链代码实例
2014/08/27 PHP
php curl 获取https请求的2种方法
2015/04/27 PHP
PHP使用正则表达式获取微博中的话题和对象名
2015/07/18 PHP
ThinkPHP安装和设置
2015/07/27 PHP
Laravel重写用户登录简单示例
2016/10/08 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
2017/07/19 PHP
[原创]PHP获取数组表示的路径方法分析【数组转字符串】
2017/09/01 PHP
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
2007/01/09 Javascript
jQuery 动画基础教程
2008/12/25 Javascript
JavaScript入门教程(1) 什么是JS
2009/01/31 Javascript
Javascript学习笔记7 原型链的原理
2010/01/11 Javascript
javascript dom代码应用 简单的相册[firefox only]
2010/06/12 Javascript
javascript的函数、创建对象、封装、属性和方法、继承
2011/03/10 Javascript
jquery星级插件、支持页面中多次使用
2012/03/25 Javascript
JS控制网页动态生成任意行列数表格的方法
2015/03/09 Javascript
Javascript中实现String.startsWith和endsWith方法
2015/06/10 Javascript
基于Vue的移动端图片裁剪组件功能
2017/11/28 Javascript
JS使用数组实现的队列功能示例
2019/03/04 Javascript
Python加pyGame实现的简单拼图游戏实例
2015/05/15 Python
Python写的一个简单监控系统
2015/06/19 Python
Python实现决策树并且使用Graphviz可视化的例子
2019/08/09 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
Selenium向iframe富文本框输入内容过程图解
2020/04/10 Python
基于jupyter代码无法在pycharm中运行的解决方法
2020/04/21 Python
Django分组聚合查询实例分享
2020/04/29 Python
python实现感知机模型的示例
2020/09/30 Python
Python list和str互转的实现示例
2020/11/16 Python
css3模拟jq点击事件的实例代码
2017/07/06 HTML / CSS
个人自我评价范文
2014/02/05 职场文书
大学生作弊检讨书
2014/02/19 职场文书
南京市纪委监察局整改方案
2014/09/16 职场文书
经费申请报告范文
2015/05/18 职场文书
MySQL的安装与配置详细教程
2021/06/26 MySQL
使用Redis做预定库存缓存功能
2022/04/02 Redis