This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
BottomSheet
一个从屏幕底部滑出的模态底部弹出层。
一个从屏幕底部滑出的模态 sheet。sheet 的可见性是受控的——通过 React state 切换 isPresented,并通过 onDismiss 将其关闭(当用户向下滑动或点击遮罩层时触发)。
在 iOS 上,如果要在另一个底部 sheet 之上显示一个底部 sheet,请将第二个BottomSheet嵌套在第一个 sheet 的内容中,而不是并排放置。这是底层 SwiftUIsheet修饰符的限制。有关更多信息,请参阅 如何呈现多个 sheets。
安装
- npx expo install @expo/uiIf you are installing this in an existing React Native app, make sure to install expo in your project.
用法
基础底部 sheet
import { useState } from 'react'; import { Host, Column, Button, BottomSheet, Text } from '@expo/ui'; export default function BottomSheetExample() { const [isPresented, setIsPresented] = useState(false); return ( <Host style={{ flex: 1 }}> <Button label="打开 sheet" onPress={() => setIsPresented(true)} /> <BottomSheet isPresented={isPresented} onDismiss={() => setIsPresented(false)}> <Column spacing={12}> <Text textStyle={{ fontSize: 18, fontWeight: '700' }}>sheet 内容</Text> <Text>向下拖动或点击遮罩层即可关闭。</Text> <Button label="关闭" onPress={() => setIsPresented(false)} /> </Column> </BottomSheet> </Host> ); }
隐藏拖拽指示器
对于没有把手的 sheet,传入 showDragIndicator={false}。
import { useState } from 'react'; import { Host, Button, BottomSheet, Text } from '@expo/ui'; export default function BottomSheetNoIndicatorExample() { const [isPresented, setIsPresented] = useState(false); return ( <Host style={{ flex: 1 }}> <Button label="打开" onPress={() => setIsPresented(true)} /> <BottomSheet isPresented={isPresented} onDismiss={() => setIsPresented(false)} showDragIndicator={false}> <Text>没有拖拽把手。</Text> </BottomSheet> </Host> ); }
Snap 点
传入 snapPoints 以便用户在多个停靠高度之间拖动 sheet。为实现跨平台一致性,你可以使用语义值 'half' 和 'full'。{ fraction } 和 { height } 形式在 iOS 和 web 上会被精确遵循。
当 sheet 内容可能比最小的 snap 点更高时,请将其包裹在 ScrollView 中,这样溢出内容才能正确滚动。
import { useState } from 'react'; import { Host, BottomSheet, Button, Column, ScrollView, Text } from '@expo/ui'; export default function BottomSheetSnapPointsExample() { const [isPresented, setIsPresented] = useState(false); return ( <Host style={{ flex: 1 }}> <Button label="Open" onPress={() => setIsPresented(true)} /> <BottomSheet isPresented={isPresented} onDismiss={() => setIsPresented(false)} snapPoints={['half', 'full']}> <ScrollView> <Column spacing={12}> <Text textStyle={{ fontSize: 20, fontWeight: '700' }}>半屏 / 全屏 sheet</Text> <Text>在半屏和全屏高度之间拖动 sheet。</Text> </Column> </ScrollView> </BottomSheet> </Host> ); }
在 Android 上,
{ fraction }和{ height }会自动对齐到最接近的'half'/'full'——底层的ModalBottomSheet只支持两个停靠状态。部分状态仅在内容足够高、超过 Material 的部分阈值时才会显示;如果你需要在短内容上显示半屏状态,请为内容设置显式高度或让其填充可用空间。
可滚动的 React Native 内容
当使用 RNHostView 包裹时,底部 sheet 支持将 React Native 列表(例如 FlatList,或高性能列表如 FlashList 或 Legend List)作为子组件。snapPoints 用于设定 sheet 的高度,列表会在该高度内滚动。启用 nestedScrollEnabled 后,列表会优先滚动自身内容;当滚动到顶部边缘后,剩余的拖动将移动 sheet。
import { useState } from 'react'; import { FlatList, Text } from 'react-native'; import { Host, BottomSheet, Button, RNHostView } from '@expo/ui'; const DATA = Array.from({ length: 50 }, (_, i) => `Item ${i + 1}`); export default function BottomSheetScrollableExample() { const [isPresented, setIsPresented] = useState(false); return ( <Host matchContents> <Button label="Open" onPress={() => setIsPresented(true)} /> <BottomSheet isPresented={isPresented} onDismiss={() => setIsPresented(false)} snapPoints={['half', 'full']}> <RNHostView> <FlatList nestedScrollEnabled style={{ flex: 1 }} data={DATA} keyExtractor={item => item} renderItem={({ item }) => <Text style={{ padding: 16 }}>{item}</Text>} /> </RNHostView> </BottomSheet> </Host> ); }
API
import { BottomSheet } from '@expo/ui';
Component
Type: React.Element<BottomSheetProps>
A modal sheet that slides up from the bottom of the screen.
Props for the BottomSheet component, a modal sheet that slides up from the bottom of the screen.
ModifierConfig[]Platform-specific modifier escape hatch. Pass an array of modifier configs
from @expo/ui/swift-ui/modifiers or @expo/ui/jetpack-compose/modifiers.
() => voidCalled when the bottom sheet is dismissed by the user (e.g. swiping down or tapping the overlay).
boolean • Default: trueWhether to show a drag indicator at the top of the sheet.
SnapPoint[]Heights the sheet can rest at.
When omitted, the sheet auto-sizes to its content.
See SnapPoint for the supported values.
Example
``['half', 'full'] — draggable between half and full
Example
``['full'] — always full height
Types
A snap point describing one of the heights a BottomSheet can rest at.
'half'— Approximately half-screen.'full'— Fully expanded.{ fraction }— A fraction of the screen height (0–1). iOS / web only.{ height }— A fixed pixel height. iOS / web only.
On Android, { fraction } and { height } snap to the nearest of 'half' / 'full'.
See the component docs for platform behavior notes.
Type: 'half' or 'full' or object shaped as below:
| Property | Type | Description |
|---|---|---|
| fraction | number | - |
Or object shaped as below:
| Property | Type | Description |
|---|---|---|
| height | number | - |