react-native 封裝選擇彈出框示例(試用ios&android)
在開(kāi)發(fā) App 的時(shí)候,經(jīng)常會(huì)使用到對(duì)話(huà)框(又叫消息框、提示框、告警框)。 在web開(kāi)發(fā)中經(jīng)常會(huì)用得到。今天就來(lái)介紹了一下react-native 封裝彈出框
之前看到react-native-image-picker中自帶了一個(gè)選擇器,可以選擇拍照還是圖庫(kù),但我們的項(xiàng)目中有多處用到這個(gè)選擇彈出框,所以就自己寫(xiě)了一下,最最重要的是ios和Android通用。先上動(dòng)態(tài)效果圖~
一、封裝要點(diǎn)
1.使用動(dòng)畫(huà)實(shí)現(xiàn)彈框布局及顯示隱藏效果
2.通過(guò)一個(gè)boolean值控制組件的顯示隱藏
3.彈框選項(xiàng)數(shù)組通過(guò)調(diào)用的js傳到彈框組件
4.組件選項(xiàng)的字體顏色通過(guò)調(diào)用js傳到組件,實(shí)現(xiàn)可拓展;
5.選擇選項(xiàng)回調(diào)方法
二、代碼實(shí)現(xiàn)
新建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 = [];//數(shù)據(jù)源 this.callback = function () { };//回調(diào)方法 } 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清空。 // 如果你使用多個(gè)timer,那么用多個(gè)變量,或者用個(gè)數(shù)組來(lái)保存引用,然后逐個(gè)clear this.timer && clearTimeout(this.timer); this.chooseTimer && clearTimeout(this.chooseTimer); } //顯示動(dòng)畫(huà) in() { Animated.parallel([ Animated.timing( this.state.opacity, { easing: Easing.linear,//一個(gè)用于定義曲線(xiàn)的漸變函數(shù) duration: 200,//動(dòng)畫(huà)持續(xù)的時(shí)間(單位是毫秒),默認(rèn)為200。 toValue: 0.8,//動(dòng)畫(huà)的最終值 } ), Animated.timing( this.state.offset, { easing: Easing.linear, duration: 200, toValue: 1, } ) ]).start(); } //隱藏動(dòng)畫(huà) 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個(gè)選項(xiàng)(包括取消) * titile: 標(biāo)題 * entityList:選擇項(xiàng)數(shù)據(jù) 數(shù)組 * tipTextColor: 字體顏色 * callback:回調(diào)方法 */ 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, }, // 提示標(biāo)題 tipTitleView: { height: 56, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: '#fff', marginLeft: 10, marginRight: 10 }, // 提示文字 tipTitleText: { color: "#999999", fontSize: 14, }, // 分割線(xiàn) 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 = ["拍照", "圖庫(kù)"]; class Demo extends Component { constructor(props) { super(props); this.showAlertSelected = this.showAlertSelected.bind(this); this.callbackSelected = this.callbackSelected.bind(this); } showAlertSelected(){ this.dialog.show("請(qǐng)選擇照片", selectedArr, '#333333', this.callbackSelected); } // 回調(diào) callbackSelected(i){ switch (i){ case 0: // 拍照 this.takePhoto(); break; case 1: // 圖庫(kù) 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> ); } }
再來(lái)一張其他界面調(diào)用該組件的效果圖~
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
如何在React項(xiàng)目中優(yōu)雅的使用對(duì)話(huà)框
在項(xiàng)目中,對(duì)話(huà)框和確認(rèn)框是使用頻率很高的組件,下面這篇文章主要給大家介紹了關(guān)于如何在React項(xiàng)目中優(yōu)雅的使用對(duì)話(huà)框的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05深入理解react-router 路由的實(shí)現(xiàn)原理
這篇文章主要介紹了深入理解react-router 路由的實(shí)現(xiàn)原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09深入理解React中es6創(chuàng)建組件this的方法
this的本質(zhì)可以這樣說(shuō),this跟作用域無(wú)關(guān)的,只跟執(zhí)行上下文有關(guān)。接下來(lái)通過(guò)本文給大家介紹React中es6創(chuàng)建組件this的方法,非常不錯(cuò),感興趣的朋友一起看看吧2016-08-08