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 相关文章推荐
原生javascript和jquery判断浏览器版本等信息
Jul 04 Javascript
jquery 实现两Select 标签项互调示例代码
Sep 25 Javascript
使用纯javascript实现放大镜效果
Mar 18 Javascript
EasyUI学习之Combobox下拉列表(1)
Dec 29 Javascript
js仿QQ邮箱收件人选择与搜索功能
Feb 10 Javascript
JavaScript运动框架 链式运动到完美运动(五)
May 18 Javascript
Vue自定义指令详解
Jul 28 Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
Feb 21 Javascript
详解JavaScript对数组操作(添加/删除/截取/排序/倒序)
Apr 28 Javascript
使用Layer组件弹出多个对话框(非嵌套)与关闭及刷新的例子
Sep 25 Javascript
async/await让异步操作同步执行的方法详解
Nov 01 Javascript
微信小程序页面渲染实现方法
Nov 06 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
PHP 5.0对象模型深度探索之绑定
2006/09/05 PHP
php UTF8 文件的签名问题
2009/10/30 PHP
php获取远程图片的两种 CURL方式和sockets方式获取远程图片
2011/11/07 PHP
php中自定义函数dump查看数组信息类似var_dump
2014/01/27 PHP
PHP合并数组+号和array_merge的区别
2015/06/25 PHP
php HTML无刷新提交表单
2016/04/05 PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
2017/02/17 PHP
对YUI扩展的Gird组件 Part-1
2007/03/10 Javascript
分享27款非常棒的jQuery 表单插件
2011/03/28 Javascript
js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS
2013/11/18 Javascript
jQuery中detach()方法用法实例
2014/12/25 Javascript
js获取字符串字节数方法小结
2015/06/09 Javascript
jQuery简单倒计时效果完整示例
2016/09/20 Javascript
简单实现jquery焦点图
2016/12/12 Javascript
Node.js中看JavaScript的引用
2017/04/22 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
2017/11/02 Javascript
Vue添加请求拦截器及vue-resource 拦截器使用
2017/11/23 Javascript
利用CDN加速react webpack打包后的文件详解
2018/02/22 Javascript
node.js爬取中关村的在线电瓶车信息
2018/11/13 Javascript
使用Vue-Awesome-Swiper实现旋转叠加轮播效果&amp;平移轮播效果
2019/08/16 Javascript
Win10下python 2.7.13 安装配置方法图文教程
2018/09/18 Python
python爬取淘宝商品销量信息
2018/11/16 Python
python利用requests库模拟post请求时json的使用教程
2018/12/07 Python
Python读取csv文件分隔符设置方法
2019/01/14 Python
Python实现的调用C语言函数功能简单实例
2019/03/13 Python
python实现图片压缩代码实例
2019/08/12 Python
Python自动化xpath实现自动抢票抢货
2020/09/19 Python
使用python对excel表格处理的一些小功能
2021/01/25 Python
个人优缺点自我评价
2014/01/27 职场文书
护士求职信
2014/07/05 职场文书
毕业生找工作求职信
2014/08/05 职场文书
入党积极分子批评与自我批评思想汇报
2014/09/14 职场文书
在职证明书范本(2014新版)
2014/09/25 职场文书
只用20行Python代码实现屏幕录制功能
2021/06/02 Python
【海涛解说】pis亲自推荐,其实你从来不会玩NW
2022/04/01 DOTA
java开发双人五子棋游戏
2022/05/06 Java/Android