react-native-pager-view

repository·master·Indexed 25 days ago

https://github.com/callstack/react-native-pager-view

A React Native wrapper for Android ViewPager2 and iOS UIPageViewController that allows users to swipe left and right through pages of data. It provides the PagerView component, the usePagerView hook, and support for react-native-reanimated handlers.

Tokens
4.7K
Snippets
9
Records
23
Agent score
85%

What's inside react-native-pager-view

  1. Link react-native-pager-view manually (React Native < 0.60)

    master

    For React Native versions older than 0.60, you may need to link the library manually.

    iOS Manual Linking

    Add the following to your Podfile:

    pod 'react-native-pager-view', :path => '../node_modules/react-native-pager-view'

    Android Manual Linking

    1. android/settings.gradle:
    include ':react-native-pager-view'
    project(':react-native-pager-view').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-pager-view/android')
    1. android/app/build.gradle:
    dependencies {
       ...
       implementation project(':react-native-pager-view')
    }
    1. android/app/src/main/.../MainApplication.java: Add the import and include PagerViewPackage in your list of exported packages:
    import com.reactnativepagerview.PagerViewPackage;
    
    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new PagerViewPackage()
      );
    }
  2. Attach Reanimated handler with onPageScroll

    master

    To use onPageScroll with react-native-reanimated, you must create an animated component and use a custom handler that utilizes useEvent and the 'worklet' directive. This allows scroll events to be processed directly on the UI thread.

    1. Define a custom hook (e.g., usePageScrollHandler) that uses useEvent to subscribe to onPageScroll events.
    2. Wrap PagerView using Animated.createAnimatedComponent(PagerView).
    3. Pass the generated handler to the onPageScroll prop of the AnimatedPagerView component.
    // 1. Define the handler
    function usePageScrollHandler(handlers, dependencies) {
      const { context, doDependenciesDiffer } = useHandler(handlers, dependencies);
      const subscribeForEvents = ['onPageScroll'];
    
      return useEvent(
        (event) => {
          'worklet';
          const { onPageScroll } = handlers;
          if (onPageScroll && event.eventName.endsWith('onPageScroll')) {
            onPageScroll(event, context);
          }
        },
        subscribeForEvents,
        doDependenciesDiffer
      );
    }
    
    // 2. Attach the event handler
    import PagerView from 'react-native-pager-view';
    import Animated from 'react-native-reanimated';
    const AnimatedPagerView = Animated.createAnimatedComponent(PagerView);
    
    const pageScrollHandler = usePageScrollHandler({
      onPageScroll: (e) => {
        'worklet';
        offset.value = e.offset;
        console.log(e.offset, e.position);
      },
    });
    
    <AnimatedPagerView onPageScroll={pageScrollHandler} />;
  3. Migrate from @react-native-community/viewpager to react-native-pager-view

    master

    When upgrading from the legacy @react-native-community/viewpager package to react-native-pager-view, you must update your import statements for both the component and its associated event types.

    • Change the component import from ViewPager to PagerView.
    • Change the package name from @react-native-community/viewpager to react-native-pager-view.
    • Update event type imports by prefixing ViewPager with PagerView (e.g., ViewPagerOnPageScrollEventData becomes PagerViewOnPageScrollEventData).
  4. Troubleshoot PagerView issues

    master

    Child View Flex Issue

    flex:1 does not work for child views. Instead, use:

    { width: '100%', height: '100%' }

    iOS UIViewControllerHierarchyInconsistency Error

    If you encounter this error on iOS, wrap your setPage call in a requestAnimationFrame:

    requestAnimationFrame(() => refPagerView.current?.setPage(index));
  5. Basic usage of PagerView

    master

    To use PagerView, import it from react-native-pager-view. Note that you can only use View components as children of PagerView.

    Android Note: If a child View has its own children, set the collapsable prop to false to prevent React Native from removing the view and rendering its children as separate pages.

    import React from 'react';
    import { StyleSheet, View, Text } from 'react-native';
    import PagerView from 'react-native-pager-view';
    
    const MyPager = () => {
      return (
        <PagerView style={styles.pagerView} initialPage={0}>
          <View key="1">
            <Text>First page</Text>
          </View>
          <View key="2">
            <Text>Second page</Text>
          </View>
        </PagerView>
      );
    };
    
    const styles = StyleSheet.create({
      pagerView: {
        flex: 1,
      },
    });
  6. Use the usePagerView hook

    master

    The usePagerView hook is a utility for managing the state and control of the <PagerView /> component. It provides a set of props and a ref to interact with the pager, such as navigating between pages, enabling/disabling scrolling, and handling page selection events.

    Key features provided by the hook:

    • AnimatedPagerView: A component wrapped in Animated.createAnimatedComponent.
    • ref: A ref to control the pager instance.
    • rest props: Includes overdragEnabled, scrollEnabled, onPageScroll, onPageSelected, onPageScrollStateChanged, and a pages array for dynamic rendering.
    export function PagerHookExample() {
      const { AnimatedPagerView, ref, ...rest } = usePagerView({ pagesAmount: 10 });
      
      return (
        <SafeAreaView style={styles.container}>
          <AnimatedPagerView
            testID="pager-view"
            ref={ref}
            style={styles.PagerView}
            initialPage={0}
            layoutDirection="ltr"
            overdrag={rest.overdragEnabled}
            scrollEnabled={rest.scrollEnabled}
            onPageScroll={rest.onPageScroll}
            onPageSelected={rest.onPageSelected}
            onPageScrollStateChanged={rest.onPageScrollStateChanged}
            pageMargin={10}
            orientation="horizontal"
          >
            {useMemo(
              () =>
                rest.pages.map((_, index) => (
                  <View
                    testID="pager-view-content"
                    key={index}
                    style={{
                      flex: 1,
                      backgroundColor: '#fdc08e',
                      alignItems: 'center',
                      padding: 20,
                    }}
                    collapsable={false}
                  >
                    <LikeCount />
                    <Text testID={`pageNumber${index}`}>
                      {`page number ${index}`}
                    </Text>
                  </View>
                )),
              [rest.pages]
            )}
          </AnimatedPagerView>
          <NavigationPanel {...rest} />
        </SafeAreaView>
      );
    }
  7. PagerView Props Reference

    master

    The following props are available on the PagerView component:

    PropTypeDescriptionPlatform
    initialPagenumberIndex of initial page that should be selectedboth
    scrollEnabledbooleanShould pager view scroll, when scroll enabledboth
    onPageScroll(e: PageScrollEvent) => voidExecuted when transitioning between pagesboth
    onPageScrollStateChanged(e: PageScrollStateChangedEvent) => voidCalled when the page scrolling state has changedboth
    onPageSelected(e: PageSelectedEvent) => voidCalled once the ViewPager finishes navigating to the selected pageboth
    pageMarginnumberBlank space to be shown between pagesboth
    keyboardDismissMode'none' | 'on-drag'Determines whether the keyboard gets dismissed in response to a dragboth
    orientationOrientationSet horizontal or vertical scrolling orientation (not dynamic)both
    overScrollModeOverScrollModeOverride default overscroll mode (auto, always, or never)Android
    offscreenPageLimitnumberNumber of pages to retain to either side of visible page(s)Android
    overdragbooleanAllows for overscrolling after reaching the end/beginningiOS
    layoutDirection'ltr' | 'rtl' | 'locale'Specifies layout direction. Defaults to localeboth
  8. PagerView Methods Reference

    master

    The following methods are available on the PagerView component instance:

    MethodDescriptionPlatform
    setPage(index: number)Scrolls to a specific page. Invalid index is ignored.both
    setPageWithoutAnimation(index: number)Scrolls to a specific page without animation. Invalid index is ignored.both
    setScrollEnabled(scrollEnabled: boolean)Imperatively enables/disables scroll.both
  9. Use the PagerView component

    master

    The PagerView component is a container that allows flipping between child views. Each child is treated as a separate page and stretched to fill the PagerView.

    Requirements:

    • All children must be <View> components (not composite components).
    • Each child must have a unique key prop.
    • You can set style properties like padding or backgroundColor on individual children.

    Layout Direction: If layoutDirection is not provided or is set to 'locale', the component automatically detects the direction using I18nManager.isRTL ('rtl' or 'ltr').

    <PagerView
      style={styles.PagerView}
      initialPage={0}>
      <View style={styles.pageStyle} key="1">
        <Text>First page</Text>
      </View>
      <View style={styles.pageStyle} key="2">
        <Text>Second page</Text>
      </View>
    </PagerView>
    
    // Styles example
    const styles = {
      PagerView: {
        flex: 1
      },
      pageStyle: {
        alignItems: 'center',
        padding: 20,
      }
    }
  10. Configure PagerView props

    master

    The PagerView component accepts several props to control its behavior, orientation, and event handling.

    Configuration Props:

    • scrollEnabled: Enables or disables user scrolling. Defaults to true.
    • layoutDirection: Sets the layout direction ('ltr' or 'rtl'). Defaults to 'ltr'.
    • initialPage: The index of the page to display initially.
    • orientation: Sets the paging direction ('horizontal' or 'vertical'). Defaults to 'horizontal'.
    • offscreenPageLimit: Number of pages to render off-screen.
    • pageMargin: Margin between pages.
    • overScrollMode: Controls overscroll behavior ('auto', 'always', or 'never'). Defaults to 'auto'.
    • overdrag: Enables or disables overdrag behavior. Defaults to false.
    • keyboardDismissMode: Determines how the keyboard behaves during paging ('none' or 'on-drag'). Defaults to 'none'.

    Event Props:

    • onPageScroll: Triggered during scrolling. Provides position and offset.
    • onPageSelected: Triggered when a new page is selected. Provides position.
    • onPageScrollStateChanged: Triggered when the scroll state changes. Provides pageScrollState ('idle', 'dragging', or 'settling').