React Native 抽屉布局
一个跨平台的 React Native Drawer 组件,在原生平台上使用 react-native-gesture-handler
和 react-native-reanimated
,在 Web 上使用 CSS 转换实现。
¥A cross-platform Drawer component for React Native implemented using react-native-gesture-handler
and react-native-reanimated
on native platforms and CSS transitions on Web.
该包不与 React Navigation 集成。如果你想将抽屉布局与 React Navigation 的导航系统集成,例如想要在抽屉中显示屏幕并能够使用 navigation.navigate
等在它们之间导航,请改用 抽屉导航器。
¥This package doesn't integrate with React Navigation. If you want to integrate the drawer layout with React Navigation's navigation system, e.g. want to show screens in the drawer and be able to navigate between them using navigation.navigate
etc, use Drawer Navigator instead.
安装
¥Installation
要使用此包,请在项目根目录中打开终端并运行:
¥To use this package, open a Terminal in the project root and run:
- npm
- Yarn
- pnpm
npm install react-native-drawer-layout
yarn add react-native-drawer-layout
pnpm add react-native-drawer-layout
然后,你需要安装和配置抽屉所需的库:
¥Then, you need to install and configure the libraries that are required by the drawer:
-
首先,安装
react-native-gesture-handler
和react-native-reanimated
(至少是版本 2 或 3)。¥First, install
react-native-gesture-handler
andreact-native-reanimated
(at least version 2 or 3).如果你有 Expo 托管项目,请在项目目录中运行:
¥If you have a Expo managed project, in your project directory, run:
npx expo install react-native-gesture-handler react-native-reanimated
如果你有一个裸露的 React Native 项目,请在项目目录中运行:
¥If you have a bare React Native project, in your project directory, run:
- 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 Babel 插件。
¥Configure the Reanimated Babel Plugin in your project following the installation guide.
-
要完成
react-native-gesture-handler
的安装,我们需要有条件地导入它。为此,请创建 2 个文件:¥To finalize the installation of
react-native-gesture-handler
, we need to conditionally import it. To do this, create 2 files:gesture-handler.native.js// Only import react-native-gesture-handler on native platforms
import 'react-native-gesture-handler';gesture-handler.js// Don't import react-native-gesture-handler on web
现在,在你的入口文件(例如
index.js
或App.js
)的顶部添加以下内容(确保它位于顶部并且之前没有其他内容):¥Now, add the following at the top (make sure it's at the top and there's nothing else before it) of your entry file, such as
index.js
orApp.js
:import './gesture-handler';
由于抽屉布局在 Web 上不使用
react-native-gesture-handler
,因此可以避免不必要地增加包大小。¥Since the drawer layout doesn't use
react-native-gesture-handler
on Web, this avoids unnecessarily increasing the bundle size.警告如果你正在为 Android 或 iOS 进行构建,请不要跳过此步骤,否则即使你的应用在开发中运行良好,也可能会在生产中崩溃。这不适用于其他平台。
¥If you are building for Android or iOS, do not skip this step, or your app may crash in production even if it works fine in development. This is not applicable to other platforms.
-
如果你使用的是 Mac 并针对 iOS 进行开发,则还需要安装 pod(通过 可可足类)来完成链接。
¥If you're on a Mac and developing for iOS, you also need to install the pods (via Cocoapods) to complete the linking.
npx pod-install ios
我们完成了!现在你可以在你的设备/模拟器上构建并运行该应用。
¥We're done! Now you can build and run the app on your device/simulator.
快速开始
¥Quick start
import * as React from 'react';
import { Text } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
import { Button } from '@react-navigation/elements';
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 参考
¥API reference
该包导出一个 Drawer
组件,该组件是你用来渲染抽屉的组件。
¥The package exports a Drawer
component which is the one you'd use to render the drawer.
Drawer
组件负责渲染带有动画和手势的抽屉侧边栏。
¥Component is responsible for rendering a drawer sidebar with animations and gestures.
抽屉属性
¥Drawer Props
open
抽屉是否打开。
¥Whether the drawer is open or not.
onOpen
抽屉打开时调用的回调。
¥Callback which is called when the drawer is opened.
onClose
抽屉关闭时调用的回调。
¥Callback which is called when the drawer is closed.
renderDrawerContent
回调返回一个 React 元素以渲染为抽屉的内容。
¥Callback which returns a react element to render as the content of the drawer.
layout
包含容器布局的对象。默认为应用窗口的尺寸。
¥Object containing the layout of the container. Defaults to the dimensions of the application's window.
drawerPosition
抽屉在屏幕上的位置。RTL 模式下默认为 right
,否则为 left
。
¥Position of the drawer on the screen. Defaults to right
in RTL mode, otherwise left
.
drawerType
抽屉的类型。它决定抽屉的外观和动画效果。
¥Type of the drawer. It determines how the drawer looks and animates.
-
front
:传统的抽屉,用覆盖层覆盖屏幕。¥
front
: Traditional drawer which covers the screen with a overlay behind it. -
back
:滑动时抽屉会显示在屏幕后面。¥
back
: The drawer is revealed behind the screen on swipe. -
slide
:屏幕和抽屉都会滑动以显示抽屉。¥
slide
: Both the screen and the drawer slide on swipe to reveal the drawer. -
permanent
:永久抽屉显示为侧边栏。¥
permanent
: A permanent drawer is shown as a sidebar.
在 iOS 上默认为 slide
,在其他平台上默认为 front
。
¥Defaults to slide
on iOS and front
on other platforms.
drawerStyle
抽屉的样式对象。你可以传递抽屉的自定义背景颜色或抽屉的自定义宽度。
¥Style object for the drawer. You can pass a custom background color for drawer or a custom width for the drawer.
overlayStyle
覆盖层的样式对象。
¥Style object for the overlay.
hideStatusBarOnOpen
抽屉打开时是否隐藏状态栏。默认为 false
。
¥Whether to hide the status bar when the drawer is open. Defaults to false
.
keyboardDismissMode
当抽屉打开时是否关闭键盘。支持的值为:
¥Whether to dismiss the keyboard when the drawer is open. Supported values are:
-
none
:当抽屉打开时,键盘不会消失。¥
none
: The keyboard will not be dismissed when the drawer is open. -
on-drag
:当通过滑动手势打开抽屉时,键盘将消失。¥
on-drag
: The keyboard will be dismissed when the drawer is opened by a swipe gesture.
默认为 on-drag
。
¥Defaults to on-drag
.
statusBarAnimation
状态栏隐藏时使用的动画。支持的值为:
¥Animation to use when the status bar is hidden. Supported values are:
-
slide
:状态栏将滑出视图。¥
slide
: The status bar will slide out of view. -
fade
:状态栏将淡出视图。¥
fade
: The status bar will fade out of view. -
none
:状态栏不会有动画。¥
none
: The status bar will not animate.
与 hideStatusBarOnOpen
结合使用。
¥Use it in combination with hideStatusBarOnOpen
.
swipeEnabled
是否启用滑动手势打开抽屉。默认为 true
。
¥Whether to enable swipe gestures to open the drawer. Defaults to true
.
仅 iOS 和 Android 支持滑动手势。
¥Swipe gestures are only supported on iOS and Android.
swipeEdgeWidth
滑动手势应在距离屏幕边缘多远的地方激活。默认为 32
。
¥How far from the edge of the screen the swipe gesture should activate. Defaults to 32
.
仅 iOS 和 Android 支持此功能。
¥This is only supported on iOS and Android.
swipeMinDistance
应激活打开抽屉的最小滑动距离。默认为 60
。
¥Minimum swipe distance that should activate opening the drawer. Defaults to 60
.
仅 iOS 和 Android 支持此功能。
¥This is only supported on iOS and Android.
swipeMinVelocity
激活打开抽屉的最小滑动速度。默认为 500
。
¥Minimum swipe velocity that should activate opening the drawer. Defaults to 500
.
仅 iOS 和 Android 支持此功能。
¥This is only supported on iOS and Android.
gestureHandlerProps
传递给底层平移手势处理程序的属性。
¥Props to pass to the underlying pan gesture handler.
仅 iOS 和 Android 支持此功能。
¥This is only supported on iOS and Android.
children
抽屉应封装的内容。
¥Content that the drawer should wrap.
useDrawerProgress
useDrawerProgress
钩子返回一个 Reanimated SharedValue
,它代表抽屉的进度。它可用于对屏幕内容进行动画处理。
¥The useDrawerProgress
hook returns a Reanimated SharedValue
which represents the progress of the drawer. It can be used to animate the content of the screen.
现代实现的示例:
¥Example with modern implementation:
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>;
}
如果你使用类组件,则可以使用 DrawerProgressContext
来获取进度值。
¥If you are using class components, you can use the DrawerProgressContext
to get the progress value.
import { DrawerProgressContext } from 'react-native-drawer-layout';
// ...
class MyComponent extends React.Component {
static contextType = DrawerProgressContext;
render() {
const progress = this.context;
// ...
}
}
useDrawerProgress
钩子(或 DrawerProgressContext
)将在 Web 上返回一个模拟值,因为 Reanimated 未在 Web 上使用。模拟值只能表示抽屉的打开状态(关闭时为 0
,打开时为 1
),而不能表示抽屉的进度。
¥The useDrawerProgress
hook (or DrawerProgressContext
) will return a mock value on Web since Reanimated is not used on Web. The mock value can only represent the open state of the drawer (0
when closed, 1
when open), and not the progress of the drawer.