文檔來源:
這是一個替代RN中 DrawerLayoutAndroid
的跨平臺組件
使用 (usage)
import DrawerLayout from 'react-native-gesture-handler/DrawerLayout';
屬性 (Properties)
-
drawerType
:'front' | 'back' | 'slide'
, 默認值front
. 3種不同的效果 -
edgeWidth
: {number} 允許定義手勢應該激活的內容視圖邊緣的距離 -
hideStatusBar
: {boolean} 打開drawer時是否隱藏狀態(tài)欄 -
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