React Native 抽屉布局
一个使用 react-native-gesture-handler
和 react-native-reanimated
实现的跨平台 React Native 抽屉组件。
此包不与 React Navigation 集成。如果您想将抽屉布局与 React Navigation 的导航系统集成,例如想要在抽屉中显示屏幕并能够使用 navigation.navigate
等在它们之间导航,请改用 抽屉导航器。
安装
要使用此包,请在项目根目录中打开一个终端并运行
- npm
- Yarn
- pnpm
npm install react-native-drawer-layout
yarn add react-native-drawer-layout
pnpm add react-native-drawer-layout
然后,您需要安装和配置抽屉所需的库
-
首先,安装
react-native-gesture-handler
和react-native-reanimated
。如果您使用的是 Expo 管理的项目,请在项目目录中运行以下命令:
npx expo install react-native-gesture-handler react-native-reanimated
如果您使用的是裸 React Native 项目,请在项目目录中运行以下命令:
- npm
- Yarn
- pnpm
npm install react-native-gesture-handler react-native-reanimated
yarn add react-native-gesture-handler react-native-reanimated
pnpm add react-native-gesture-handler react-native-reanimated
抽屉支持 Reanimated 1 和最新版本的 Reanimated。如果您想使用最新版本的 Reanimated,请确保按照 安装指南 进行配置。
-
要完成
react-native-gesture-handler
的安装,请将以下代码添加到您的入口文件(例如index.js
或App.js
)的 **顶部**(确保它位于顶部,并且前面没有其他内容):import 'react-native-gesture-handler';
警告如果您正在为 Android 或 iOS 构建,请不要跳过此步骤,否则您的应用程序可能会在生产环境中崩溃,即使它在开发环境中运行良好。这并不适用于其他平台。
-
如果您使用的是 Mac 并为 iOS 开发,您还需要安装 pods(通过 Cocoapods)来完成链接。
npx pod-install ios
我们完成了!现在您可以构建并在您的设备/模拟器上运行应用程序。
快速入门
import * as React from 'react';
import { Button, Text } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
export default function DrawerExample() {
const [open, setOpen] = React.useState(false);
return (
<Drawer
open={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
renderDrawerContent={() => {
return <Text>Drawer content</Text>;
}}
>
<Button
onPress={() => setOpen((prevOpen) => !prevOpen)}
title={`${open ? 'Close' : 'Open'} drawer`}
/>
</Drawer>
);
}
API 参考
该包导出一个 Drawer
组件,您可以使用它来渲染抽屉。
Drawer
负责使用动画和手势渲染抽屉的组件。
抽屉属性
open
抽屉是否打开。
onOpen
当抽屉打开时调用的回调函数。
onClose
当抽屉关闭时调用的回调函数。
renderDrawerContent
返回一个 React 元素作为抽屉内容的回调函数。
layout
包含容器布局的对象。默认值为应用程序窗口的尺寸。
drawerPosition
抽屉在屏幕上的位置。在 RTL 模式下默认为 right
,否则为 left
。
drawerType
抽屉的类型。它决定了抽屉的外观和动画效果。
front
: 传统的抽屉,它覆盖屏幕,并在其后面显示一个叠加层。back
: 抽屉在滑动时显示在屏幕后面。slide
: 屏幕和抽屉在滑动时都会滑动以显示抽屉。permanent
: 永久抽屉显示为侧边栏。
在 iOS 上默认为 slide
,在其他平台上默认为 front
。
drawerStyle
抽屉的样式对象。您可以为抽屉传递自定义背景颜色或自定义宽度。
overlayStyle
叠加层的样式对象。
hideStatusBarOnOpen
是否在抽屉打开时隐藏状态栏。默认为 false
。
keyboardDismissMode
是否在抽屉打开时关闭键盘。支持的值为
none
: 抽屉打开时不会关闭键盘。on-drag
: 当抽屉通过滑动手势打开时,键盘将被关闭。
默认为 on-drag
。
statusBarAnimation
隐藏状态栏时使用的动画。支持的值为
slide
: 状态栏将从视图中滑出。fade
: 状态栏将从视图中淡出。none
: 状态栏不会动画。
与 hideStatusBarOnOpen
结合使用。
swipeEnabled
是否启用滑动手势来打开抽屉。默认为 true
。
滑动手势仅在 iOS 和 Android 上受支持。
swipeEdgeWidth
滑动操作激活抽屉的屏幕边缘距离。默认值为 32
。
此功能仅在 iOS 和 Android 上受支持。
swipeMinDistance
激活打开抽屉所需的最小滑动距离。默认值为 60
。
此功能仅在 iOS 和 Android 上受支持。
swipeMinVelocity
激活打开抽屉所需的最小滑动速度。默认值为 500
。
此功能仅在 iOS 和 Android 上受支持。
gestureHandlerProps
传递给底层平移手势处理程序的属性。
此功能仅在 iOS 和 Android 上受支持。
children
抽屉应包裹的内容。
useDrawerProgress
useDrawerProgress
钩子返回一个 Reanimated SharedValue(使用现代实现)或 Reanimated Node(使用传统实现),它表示抽屉的进度。它可以用来动画化屏幕内容。
使用现代实现的示例
import { Animated } from 'react-native-reanimated';
import { useDrawerProgress } from 'react-native-drawer-layout';
// ...
function MyComponent() {
const progress = useDrawerProgress();
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [
{
translateX: interpolate(progress, [0, 1], [-100, 0]),
},
],
};
});
return <Animated.View style={animatedStyle}>{/* ... */}</Animated.View>;
}
使用传统实现的示例
import { Animated } from 'react-native-reanimated';
import { useDrawerProgress } from 'react-native-drawer-layout';
// ...
function MyComponent() {
const progress = useDrawerProgress();
// If you are on react-native-reanimated 1.x, use `Animated.interpolate` instead of `Animated.interpolateNode`
const translateX = Animated.interpolateNode(progress, {
inputRange: [0, 1],
outputRange: [-100, 0],
});
return (
<Animated.View style={{ transform: [{ translateX }] }}>
{/* ... */}
</Animated.View>
);
}
如果您使用的是类组件,可以使用 DrawerProgressContext
获取进度值。
import { DrawerProgressContext } from 'react-native-drawer-layout';
// ...
class MyComponent extends React.Component {
static contextType = DrawerProgressContext;
render() {
const progress = this.context;
// ...
}
}