首页 > 编程 > JavaScript > 正文

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

2019-11-19 16:06:45
字体:
来源:转载
供稿:网友

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

之前看到react-native-image-picker中自带了一个选择器,可以选择拍照还是图库,但我们的项目中有多处用到这个选择弹出框,所以就自己写了一下,最最重要的是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>    );  } }

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表