在开发 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> ); } }
再来一张其他界面调用该组件的效果图~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
暂无评论...
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
2024年11月26日
2024年11月26日
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]