react-native 封装选择弹出框示例(试用ios&android)
程序员文章站
2022-05-26 09:01:56
在开发 app 的时候,经常会使用到对话框(又叫消息框、提示框、告警框)。 在web开发中经常会用得到。今天就来介绍了一下react-native 封装弹出框
之前看...
在开发 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> ); } }
再来一张其他界面调用该组件的效果图~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。