This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 57).
PagerView
一个与 react-native-pager-view 兼容的水平分页视图。
一个与 react-native-pager-view API 兼容的 PagerView 组件。它封装了平台特定的 @expo/ui 原语:Android 上的 Jetpack Compose HorizontalPager,以及 iOS 上带分页的 SwiftUI ScrollView。每个子元素都会成为独立页面,并拉伸以填满 pager。
如果你需要对平台特定的分页行为或修饰器进行更底层的控制,请直接使用原生原语。在 iOS 上,使用 page 样式的 TabView 也会渲染一个水平 pager,并且当你希望使用 SwiftUI 内置的页面指示器时,它可能更合适。
安装
- npx expo install @expo/uiIf you are installing this in an existing React Native app, make sure to install expo in your project.
如果你需要以下任一功能,可以选择安装 react-native-worklets:
- iOS 上带动画的
setPage。 没有 worklets 时,iOS 的setPage会退化为无动画跳转。Android 无论如何都会进行动画。 - 每帧都会调用、并保持在 UI 线程上的
onPageScroll回调。 当你的onPageScroll处理函数本身就是一个 worklet 时,它会每帧同步在 UI 线程上运行,而不是切回 JS 线程。没有 worklets 时,回调仍然会触发——只是会在 JS 线程上运行。
从 react-native-pager-view 迁移
通过从 @expo/ui/community/pager-view 导入 PagerView 来更新 import 语句:
import PagerView from 'react-native-pager-view'; // becomes: import PagerView from '@expo/ui/community/pager-view';
在切换之前,你应该了解这些变化:
- 不支持
orientation="vertical"、keyboardDismissMode、overdrag和overScrollMode。 - 不提供
usePagerViewhook——请改用ref。 - 在 iOS 上,
onPageScroll和onPageScrollStateChanged仅在 iOS 18+ 上触发。
完整列表请参见平台行为。
基本用法
import { useRef } from 'react'; import { Button, StyleSheet, Text, View } from 'react-native'; import PagerView, { type PagerViewRef } from '@expo/ui/community/pager-view'; export default function PagerViewExample() { const pagerRef = useRef<PagerViewRef>(null); return ( <View style={{ flex: 1 }}> <PagerView ref={pagerRef} style={{ flex: 1 }} initialPage={0} onPageSelected={event => { console.log('selected page', event.nativeEvent.position); }}> <View key="one" style={[styles.page, { backgroundColor: '#fde68a' }]}> <Text>Page one</Text> </View> <View key="two" style={[styles.page, { backgroundColor: '#bfdbfe' }]}> <Text>Page two</Text> </View> <View key="three" style={[styles.page, { backgroundColor: '#bbf7d0' }]}> <Text>Page three</Text> </View> </PagerView> <Button title="Go to page 2" onPress={() => pagerRef.current?.setPage(1)} /> </View> ); } const styles = StyleSheet.create({ page: { flex: 1, alignItems: 'center', justifyContent: 'center' }, });
平台行为
Web 不受支持,在 web 上渲染 PagerView 会在运行时抛出错误。
| 功能 | Android | iOS |
|---|---|---|
| 最低平台版本 | 任意受支持版本 | iOS 17+ 才支持分页。在 iOS 16 上,视图会水平滚动,但页面不会吸附 |
onPageScroll / onPageScrollStateChanged | 仅限 iOS 18+。在 iOS 17 上,它们永远不会触发,且组件在挂载时会记录一条开发警告 | |
带动画的 setPage | 原生 pager 动画 | 通过 react-native-worklets 路由。如果未安装该包,则回退为无动画跳转 |
layoutDirection | ||
offscreenPageLimit | ||
pageMargin |
与上游 react-native-pager-view 相比的其他差异:
- 不支持
orientation="vertical"、keyboardDismissMode、overdrag和overScrollMode。仅提供水平分页,其余配置会回退到平台 pager 的默认值。 - 不提供
usePagerViewhook。请使用PagerView的ref来访问setPage、setPageWithoutAnimation和setScrollEnabled。 setScrollEnabled会触发重新渲染,因此新值会作为 prop 传递到原生视图。它仍然适用于从非 React 上下文切换,例如基于 ref 的手势处理器。borderRadius样式在两个平台上都适用。在 Android 上,只有数值才能裁剪 pager。底层的 Compose 容器会静默忽略诸如'50%'之类的字符串值。
API
import PagerView from '@expo/ui/community/pager-view';
Component
Type: React.Element<PagerViewProps>
A drop-in replacement for react-native-pager-view. Renders a horizontally
paged view backed by Jetpack Compose's HorizontalPager on Android and
SwiftUI on iOS. Each child is treated as a separate page.
ReactNodePages of the pager. Each child is treated as a separate page and
stretched to fill the pager. Each child should have a stable key.
number • Default: 0Index of the page that is initially selected. Read once on mount;
later changes are ignored. To navigate after mount, call
ref.setPage() or ref.setPageWithoutAnimation().
string • Default: 'ltr'Layout direction for paging.
Acceptable values are: 'ltr' | 'rtl'
numberNumber of pages kept off-screen on each side of the visible page.
(event: PagerViewOnPageScrollEvent) => voidFires continuously while a swipe is in progress. The event's position
is the index of the leading visible page; offset is the fractional
progress toward the next page in the [0, 1) range.
Mark this handler with 'worklet' (requires react-native-worklets)
to run it synchronously on the UI thread every frame.
(event: PageScrollStateChangedEvent) => voidFires when the scroll state changes between idle, dragging,
and settling.
(event: PagerViewOnPageSelectedEvent) => voidFires when a page is fully selected. The event's position is the
index of the new page.
Ref<PagerViewRef>Ref handle exposing imperative setPage, setPageWithoutAnimation,
and setScrollEnabled methods.
boolean • Default: trueWhether the user can swipe between pages.
Types
Type: NativeSyntheticEvent<PagerViewOnPageScrollEventData>
Type: Readonly<{
offset: number,
position: number
}>
Type: NativeSyntheticEvent<PagerViewOnPageSelectedEventData>
Type: Readonly<{
position: number
}>
Ref handle for the PagerView component.
| Property | Type | Description |
|---|---|---|
| setPage | (selectedPage: number) => void | Animate the pager to the given page index. Out-of-range indices are
silently ignored. On iOS the animation requires |
| setPageWithoutAnimation | (selectedPage: number) => void | Jump to the given page index without an animation. |
| setScrollEnabled | (scrollEnabled: boolean) => void | Imperatively enable or disable user scrolling.
|
Type: NativeSyntheticEvent<PageScrollStateChangedEventData>
Type: Readonly<{
pageScrollState: 'idle' | 'dragging' | 'settling'
}>