文档来源:
这是一个替代RN中 DrawerLayoutAndroid
的跨平台组件
使用 (usage)
import DrawerLayout from 'react-native-gesture-handler/DrawerLayout';
属性 (Properties)
-
drawerType
:'front' | 'back' | 'slide'
, 默认值front
. 3种不同的效果 -
edgeWidth
: {number} 允许定义手势应该激活的内容视图边缘的距离 -
hideStatusBar
: {boolean} 打开drawer时是否隐藏状态栏 -
statusBarAnimation
:'slide' | 'none' | 'fade'
,默认值slide
. 当hideStatusBar
设置为true时使用 -
overlayColor
:遮罩背景色,默认是black
,颜色值需要是一个不包含alpha透明度的值,因为Drawer自身默认透明度从0%动画到70% -
renderNavigationView
: {function} 必需参数。这个函数接受一个Animated Value
作为参数,用于显示打开或关闭drawer动画过程(当关闭时,progress为0;当打开时,progress为1). 这个可用于 drawer组件在打开或关闭时给其children添加动画效果 -
children
: {Component | function} 默认是组件,直接被drawer包裹。也可以是一个函数,这个函数接受一个Animated Value
作为参数,用于显示打开或关闭drawer动画过程(当关闭时,progress为0;当打开时,progress为1),这个和上面的renderNavigationView
一样
另外,其余的属性请参考 DrawerLayoutAndroid
示例
DrawerLayout 在RN应用中还是很常见的一种模式,这个例子基本上就是Drawer常见的使用方式
import React, { PureComponent } from 'react';
import { Platform, StyleSheet, Text, Animated, View, TextInput, Dimensions, SafeAreaView } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
import DrawerLayout from 'react-native-gesture-handler/DrawerLayout';
const TYPES = ['front', 'back', 'back', 'slide'];
const PARALLAX = [false, false, true, false];
const {width: DEVICE_WIDTH} = Dimensions.get('window');
const styles = StyleSheet.create({
container: {
flex: 1,
},
page: {
...StyleSheet.absoluteFillObject,
alignItems: 'center',
paddingTop: 40,
backgroundColor: 'gray',
},
pageText: {
fontSize: 21,
color: 'white',
},
rectButton: {
height: 60,
padding: 10,
alignSelf: 'stretch',
alignItems: 'center',
justifyContent: 'center',
marginTop: 20,
backgroundColor: 'white',
},
rectButtonText: {
backgroundColor: 'transparent',
},
drawerContainer: {
flex: 1,
paddingTop: 30,
},
pageInput: {
height: 60,
padding: 10,
alignSelf: 'stretch',
alignItems: 'center',
justifyContent: 'center',
marginTop: 20,
backgroundColor: '#eee',
},
drawerText: {
margin: 10,
fontSize: 15,
textAlign: 'left',
},
});
// 被DrawerLayout包裹的页面
const Page = ({
fromLeft, // 是否在左边打开Drawer
type,
parallaxOn, // 是否使用动画效果
flipSide, // 切换Drawer所在位置 在左边还是右边
nextType, // 切换 type 的值
openDrawer,
}) => (
<View style={styles.page}>
<Text style={styles.pageText}>Hi DrawerLayout Demo</Text>
<RectButton style={styles.rectButton} onPress={flipSide}>
<Text>Drawer {fromLeft ? '在左边' : '在右边'}! -> 点击按钮切换</Text>
</RectButton>
<RectButton style={styles.rectButton} onPress={nextType}>
<Text style={styles.rectButtonText}>
抽屉类型 '{type}
{parallaxOn && ' with parallax'}'! -> Next
</Text>
</RectButton>
<RectButton style={styles.rectButton} onPress={openDrawer}>
<Text style={styles.rectButtonText}>打开侧边栏</Text>
</RectButton>
<TextInput
style={styles.pageInput}
placeholder='使用拖动打开drawer时 键盘会自动收起'
/>
</View>
);
export default class DrawerExample extends PureComponent {
state = {
fromLeft: true, // 是否在左边
type: 0,
};
// 渲染动画效果
// 使用 progressValue 动画值 进行插值操作
renderParallaxDrawer = progressValue => {
const parallax = progressValue.interpolate({
inputRange: [0, 1],
outputRange: [this.state.fromLeft ? -50 : 50, 0]
});
const animatedStyles = {
transform: [
{ translateX: parallax },
],
};
return (
<Animated.View
style={[styles.drawerContainer, animatedStyles]}
>
<Text style={styles.drawerText}>侧边栏抽屉</Text>
<Text style={styles.drawerText}>
当拖动侧边栏抽屉时,观察parallax动画
</Text>
</Animated.View>
)
}
// 普通的抽屉
renderDrawer = () => {
return (
<View style={styles.drawerContainer}>
<Text style={styles.drawerText}>这就是抽屉</Text>
</View>
);
}
render() {
const drawerType = TYPES[this.state.type]; // ['front', 'back', 'back', 'slide'];
const parallax = PARALLAX[this.state.type]; // 是否使用renderParallaxDrawer函数 [false, false, true, false] 和上面的drawerType相互对应
// console.log('parallax, this.state.type', parallax, this.state.type)
const position = this.state.fromLeft ? DrawerLayout.positions.Left : DrawerLayout.positions.Right; // 抽屉所在位置
// const position = this.state.fromLeft ? 'left' : 'right'; // 或者写为这个样子也可以
return (
<View style={styles.container}>
<DrawerLayout
ref={drawer => {this.drawer = drawer}}
drawerWidth={DEVICE_WIDTH - 50}
drawerType={drawerType}
keyboardDismissMode='on-drag'
drawerPosition={position}
drawerBackgroundColor='#4ae'
overlayColor={drawerType === 'front' ? '#000' : '#6a1'}
renderNavigationView={
parallax ? this.renderParallaxDrawer : this.renderDrawer
}
contentContainerStyle={
// 注意 drawerType 为 'front' 时,不要添加阴影效果,如果添加可能导致Drawer打不开
drawerType === 'front'
? {}
: Platform.select({
ios: {
shadowColor: '#000',
shadowOpacity: 0.5,
shadowOffset: { width: 0, height: 2 },
shadowRadius: 60,
},
android: {
elevation: 100,
backgroundColor: '#000',
},
})
}
>
<Page
type={drawerType}
fromLeft={this.state.fromLeft}
parallaxOn={parallax}
flipSide={() => this.setState({ fromLeft: !this.state.fromLeft })}
nextType={() =>
this.setState({ type: (this.state.type + 1) % TYPES.length })}
openDrawer={() => this.drawer.openDrawer()}
/>
</DrawerLayout>
</View>
)
}
}
2019年04月03日22:08:16