选择弹出模态框
import React from 'react'
import {Animated, Easing, Dimensions,TouchableOpacity,BackHandler} from 'react-native'
const { width, height } = Dimensions.get("screen")
/**
* 自定义自下而上淡入淡出弹框
*/
export class OptionModel extends React.Component{
constructor(state) {
super(state)
this.state = {
offset: new Animated.Value(0),
fadeOutOpacity: new Animated.Value(0),
show: false,
};
}
componentDidMount(){
BackHandler.addEventListener('hardwareBackPress',this.onBackAndroid)
}
componentWillUnmount(){
this.hide()
BackHandler.removeEventListener('hardwareBackPress',this.onBackAndroid);
}
onBackAndroid=()=>{
this.hide()
if(this.state.show){
return true;
}else{
return false;
}
}
show(){
this.setState({show:true})
Animated.parallel(
[
Animated.timing(
this.state.fadeOutOpacity,
{
toValue: 1,//透明度动画最终值
duration: 300,//动画时长3000毫秒
easing:Easing.inOut(Easing.poly(4)),
useNativeDriver: true
}
),
Animated.spring(
this.state.offset,
{
friction:7, //弹跳系数
tension:20,
// easing: Easing.out(Easing.poly(4)),
// duration: 250,
toValue: 1,
useNativeDriver: true
}
)
],
{
stopTogether: false
}
).start()
}
hide(){
Animated.parallel(
[
Animated.timing(
this.state.fadeOutOpacity,
{
toValue: 0,//透明度动画最终值
duration: 300,//动画时长3000毫秒
easing: Easing.in(Easing.poly(8)),
useNativeDriver: true
}
),
Animated.spring(
this.state.offset,
{
friction:7, //弹跳系数
tension:20,
// easing: Easing.in(Easing.poly(4)),
// duration: 250,
toValue: 0,
useNativeDriver: true
}
)
],
{
stopTogether: false
}
).start()
setTimeout(
() => this.setState({ show: false }),
300
)
}
render(){
const {heights,children} = this.props;
if(this.state.show){
return(<Animated.View style={{width:width,backgroundColor: 'rgba(0, 0, 0, 0.3)',position:'absolute',
top: 0,
zIndex: 9,
height: height ,
opacity: this.state.fadeOutOpacity
}}>
<TouchableOpacity style={{flex:1}} onPress={()=>this.hide()}></TouchableOpacity>
<Animated.View style={{zIndex:15,
transform: [{
translateY: this.state.offset.interpolate({
inputRange: [0, 1],
outputRange: [heights,0]
}),
}]
}}>
{children}
</Animated.View>
</Animated.View>)
}else{
return false
}
}
}
实现代码
点击显示按钮
<TouchableOpacity onPress={() => this.refs.OptionModelView.show()} >
<Text style={{fontSize : 18}} >显示</Text>
</TouchableOpacity>
实现代码
data数据结构,也可以自己自定义;
data = [
{name : string, value : srting},
{name : string, value : srting},
{name : string, value : srting}
]
<OptionModel ref={'OptionModelView'} heights={300}>
<View style={{height:300, backgroundColor:'white', width : '100%', paddingVertical : 10, paddingBottom : 100 }} >
<ScrollView showsHorizontalScrollIndicator={false} >
{
data.map((item ,index) => {
let check = (item['value'] === defaultValue);
return(
<TouchableOpacity
key={`${index}`}
style={{
width:'100%', flexDirection:'row', justifyContent:'center',
paddingVertical : 10,borderBottomWidth : 1, borderBottomColor : '#eee', textAlign : 'center'
}}
onPress={() => {
this.setState({ defaultValue: item['value']})
}}
>
<Text style={{color:(check ? '#0793D2' : 'black'), fontSize : 18}} >{item['name'] || '--'}</Text>
</TouchableOpacity>
)
})
}
</ScrollView>
</View>
</OptionModel>