react-native系列(10)组件篇:Modal模态框实现弹窗效果
模态框应用于界面弹窗,为用户提供通知、选择、浏览等功能的组件。在RN中,模态框通过Moadl标签引用。使用时注意,可以把Modal看成一个仅提供功能的外壳,它不包含任何样式,只负责显示/隐藏和动画效果实现。Modal的子组件通常为一个View容器,在该View容器实现渲染界面和样式相关。在很多APP应用模态框的时候,出于视觉的优化,Modal子组件最外层的View容器为一层占满全屏的半透明背景层。
模态框应用于界面弹窗,为用户提供通知、选择、浏览等功能的组件。在RN中,模态框通过Moadl标签引用。使用时注意,可以把Modal看成一个仅提供功能的外壳,它不包含任何样式,只负责显示/隐藏和动画效果实现。Modal的子组件通常为一个View容器,在该View容器实现渲染界面和样式相关。在很多APP应用模态框的时候,出于视觉的优化,Modal子组件最外层的View容器为一层占满全屏的半透明背景层。
Modal的属性:
属性 | 描述 |
---|---|
animationType | 指定了 modal 的动画类型。类型:slide 从底部滑入滑出|fade 淡入淡出|none 没有动画 |
transparent | 背景是否透明,默认为白色,当为true时表示背景为透明 |
visible | boolean值,是否显示 modal 窗口 |
onRequestClose | 回调会在用户按下 Android 设备上的后退按键或是 Apple TV 上的菜单键时触发。请务必注意本属性在 Android 平台上为必填,且会在 modal 处于开启状态时阻止BackHandler事件 |
onShow | 回调函数会在 modal 显示时调用 |
贴士代码:
import React from 'react';
import { View, Text, Modal, StyleSheet, Button } from 'react-native';
class ModalComp extends React.Component{
state = {
modalVisible: false
};
_openModalWin = () => {
this.setState({modalVisible: true});
}
_closeModalWin = () => {
this.setState({modalVisible: false});
}
render(){
return(
<View style={styles.container}>
<View style={styles.contentStyle}>
<Text style={styles.contentTextStyle}>
ModalComp
</Text>
<Button
title="打开Modal窗口"
color="#841584"
onPress={this._openModalWin}
/>
</View>
<Modal
animationType='fade' // 指定了 modal 的动画类型。类型:slide 从底部滑入滑出|fade 淡入淡出|none 没有动画
transparent={true} // 背景是否透明,默认为白色,当为true时表示背景为透明。
visible={this.state.modalVisible} // 是否显示 modal 窗口
onRequestClose={() => { this._closeModalWin(); }} // 回调会在用户按下 Android 设备上的后退按键或是 Apple TV 上的菜单键时触发。请务必注意本属性在 Android 平台上为必填,且会在 modal 处于开启状态时阻止BackHandler事件
onShow={()=>{console.log('modal窗口显示了');}} // 回调函数会在 modal 显示时调用
>
<View style={styles.modalLayer}>
<View style={styles.modalContainer}>
<Text style={styles.modalTitleStyle}>这是个Modal窗口!</Text>
<View style={styles.modalButtonStyle}>
<Button
title='取消'
color="#A4A4A4"
onPress={this._closeModalWin}
></Button>
</View>
</View>
</View>
</Modal>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
contentStyle: {
padding:30
},
contentTextStyle: {
textAlign: 'center',
fontSize: 26
},
modalLayer: {
backgroundColor: 'rgba(0, 0, 0, 0.45)',
flex: 1,
justifyContent: 'center',
padding: 32
},
modalContainer: {
height: 300,
backgroundColor: 'white',
justifyContent: 'center'
},
modalTitleStyle: {
textAlign: 'center',
fontSize: 26
},
modalButtonStyle: {
paddingLeft: 30,
paddingRight: 30,
marginTop: 10
}
});
export default ModalComp;
效果:
还有一种常见的模态框应用场景,就是从底部弹出一组可选菜单,这类组件叫做ActionSheet组件。
贴上代码:ActionSheet组件
import React, {Component} from 'react';
import {
View,
StyleSheet,
Text,
Modal,
TouchableOpacity,
Dimensions
} from 'react-native';
import PropTypes from 'prop-types';
const {width} = Dimensions.get('window');
class ActionSheetComp extends Component{
// 入参类型
static propTypes={
items:PropTypes.array,
modalTitle:PropTypes.string,
visible: PropTypes.bool
}
// 默认值
static defaultProps={
items:[
{
title: '拍照',
click: () => {
console.log('拍照');
}
},
{
title: '录像',
click: () => {
console.log('录像');
}
}
],
modalTitle:'你需要拍照或录像?',
visible: false
}
state = {
modalVisible: this.props.visible,
};
// 该钩子函数表示当父组件的props入参改变时调用,常用于父组件入参变化影响子组件渲染
UNSAFE_componentWillReceiveProps(newProps){
this.setState({modalVisible:newProps.visible});
}
cancelModal(){
this.setState({modalVisible:false});
}
render(){
let actionSheets = this.props.items.map((item,i)=>{
return(
<TouchableOpacity
key={i}
style={styles.actionItem}
onPress={item.click}>
<Text style={styles.actionItemTitle}>
{item.title}
</Text>
</TouchableOpacity>
);
});
return (
<Modal
animationType="slide"
visible={this.state.modalVisible}
transparent={true}
onRequestClose={()=>this.setState({modalVisible:false})}
>
<View style={styles.modalStyle}>
<View style={styles.subView}>
<View style={styles.itemContainer}>
<Text style={styles.actionTitle}>
{this.props.modalTitle}
</Text>
{actionSheets}
</View>
<View style={[styles.itemContainer]}>
<TouchableOpacity
style={[styles.actionItem, {borderTopWidth:0}]}
onPress={()=>this.setState({modalVisible:false})}>
<Text style={styles.actionItemTitle}>取消</Text>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
);
}
}
const styles = StyleSheet.create({
modalStyle:{
justifyContent:'flex-end',
alignItems:'center',
flex:1
},
subView:{
justifyContent:'flex-end',
alignItems:'center',
alignSelf:'stretch',
width:width,
},
itemContainer:{
marginLeft:15,
marginRight:15,
marginBottom:15,
borderRadius:6,
backgroundColor:'#fff',
justifyContent:'center',
alignItems:'center',
},
actionItem:{
width:width-30,
height:45,
alignItems:'center',
justifyContent:'center',
borderTopColor:'#cccccc',
borderTopWidth:0.5,
},
actionTitle:{
fontSize:13,
color:'#808080',
textAlign:'center',
paddingTop:10,
paddingBottom:10,
paddingLeft:15,
paddingRight:15,
},
actionItemTitle:{
fontSize:16,
color:'#444444',
textAlign:'center',
},
});
export default ActionSheetComp;
引用组件:
import React, { Component } from 'react';
import { View, Button } from 'react-native';
import ActionSheetComp from '../example/comp/ActionSheetComp';
class MainView extends Component {
state = {
visible: false
}
_showModal = () => {
this.setState({visible:true});
}
render(){
return (
<View style={{flex:1, backgroundColor: '#E4E4E4'}}>
<Button
title='显示'
onPress={this._showModal}
/>
<ActionSheetComp visible={this.state.visible} />
</View>
);
}
}
export default MainView;
效果:
更多推荐
所有评论(0)