react-native 封裝選擇彈出框示例(試用ios&android)
在開發(fā) App 的時(shí)候,經(jīng)常會(huì)使用到對話框(又叫消息框、提示框、告警框)。 在web開發(fā)中經(jīng)常會(huì)用得到。今天就來介紹了一下react-native 封裝彈出框
之前看到react-native-image-picker中自帶了一個(gè)選擇器,可以選擇拍照還是圖庫,但我們的項(xiàng)目中有多處用到這個(gè)選擇彈出框,所以就自己寫了一下,最最重要的是ios和Android通用。先上動(dòng)態(tài)效果圖~

一、封裝要點(diǎn)
1.使用動(dòng)畫實(shí)現(xiàn)彈框布局及顯示隱藏效果
2.通過一個(gè)boolean值控制組件的顯示隱藏
3.彈框選項(xiàng)數(shù)組通過調(diào)用的js傳到彈框組件
4.組件選項(xiàng)的字體顏色通過調(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ù)組來保存引用,然后逐個(gè)clear
this.timer && clearTimeout(this.timer);
this.chooseTimer && clearTimeout(this.chooseTimer);
}
//顯示動(dòng)畫
in() {
Animated.parallel([
Animated.timing(
this.state.opacity,
{
easing: Easing.linear,//一個(gè)用于定義曲線的漸變函數(shù)
duration: 200,//動(dòng)畫持續(xù)的時(shí)間(單位是毫秒),默認(rèn)為200。
toValue: 0.8,//動(dòng)畫的最終值
}
),
Animated.timing(
this.state.offset,
{
easing: Easing.linear,
duration: 200,
toValue: 1,
}
)
]).start();
}
//隱藏動(dòng)畫
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,
},
// 分割線
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);
}
// 回調(diào)
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>
);
}
}
再來一張其他界面調(diào)用該組件的效果圖~

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
如何在React項(xiàng)目中優(yōu)雅的使用對話框
在項(xiàng)目中,對話框和確認(rèn)框是使用頻率很高的組件,下面這篇文章主要給大家介紹了關(guān)于如何在React項(xiàng)目中優(yōu)雅的使用對話框的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
深入理解react-router 路由的實(shí)現(xiàn)原理
這篇文章主要介紹了深入理解react-router 路由的實(shí)現(xiàn)原理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09
深入理解React中es6創(chuàng)建組件this的方法
this的本質(zhì)可以這樣說,this跟作用域無關(guān)的,只跟執(zhí)行上下文有關(guān)。接下來通過本文給大家介紹React中es6創(chuàng)建組件this的方法,非常不錯(cuò),感興趣的朋友一起看看吧2016-08-08

