21

I am using this library https://reactnavigation.org/docs/intro/ to build android by react-native. I can make the navigation happens on android device but how I can make the screen slide in from the right and fade in from the left. It seems that this behaviour happens on iOS device but not in Android. Is there any animation configuration for android app?

Please see below animation. This is recorded in iOS.

enter image description here

robocub
  • 259
  • 2
  • 10
Joey Yi Zhao
  • 37,514
  • 71
  • 268
  • 523

8 Answers8

29

Starting from : "@react-navigation/native": "^5.5.1",

import {createStackNavigator, TransitionPresets} from '@react-navigation/stack';


const TransitionScreenOptions = {
  ...TransitionPresets.SlideFromRightIOS, // This is where the transition happens
};

const CreditStack = createStackNavigator();

function CreditStackScreen() {
  return (
    <CreditStack.Navigator screenOptions={TransitionScreenOptions}> // Don't forget the screen options
      <CreditStack.Screen
        name="Credit"
        component={HomeScreen}
        options={headerWithLogo}
      />
      <HomeStack.Screen
        name="WorkerDetails"
        component={WorkerDetails}
        options={headerWithLogoAndBackBtn}
      />
    </CreditStack.Navigator>
  );
}

You can watch this video to understand more: https://www.youtube.com/watch?v=PvjV96CNPqM&ab_channel=UnsureProgrammer

  • 2
    It will not work if you follow the last react-navigation docs (https://reactnavigation.org/docs/hello-react-navigation) because you will end up using createNativeStackNavigator, not createStackNavigator: the difference is that many of the options your can pass to the latter cannot be passed to the former. In that case you can pass presentation:"card" and animation: 'slide_from_right' in your Navigator's screenOptions prop – Apperside Dec 01 '22 at 07:49
  • @Apperside Thank you for the information. I've added the version when I wrote this to avoid conflicts. Can you please add what you wrote as an answer so people can find it in the future? Thanks! – Mohamed Sabry Abed Dec 02 '22 at 18:30
  • 1
    Hello @Mohamed, I've added an answer with an in-depth explanation – Apperside Dec 09 '22 at 06:39
22

You should use transitionConfig to override default screen transitions as written on this page.

Unfortunately there is no example provided how that function works but you can find some examples in this file: \react-navigation\lib\views\CardStackStyleInterpolator.js

So your code should look like this:

 const navigator = StackNavigator(scenes, {
transitionConfig: () => ({
    screenInterpolator: sceneProps => {
        const { layout, position, scene } = sceneProps;
        const { index } = scene;

        const translateX = position.interpolate({
            inputRange: [index - 1, index, index + 1],
            outputRange: [layout.initWidth, 0, 0]
        });

        const opacity = position.interpolate({
            inputRange: [
                index - 1,
                index - 0.99,
                index,
                index + 0.99,
                index + 1
            ],
            outputRange: [0, 1, 1, 0.3, 0]
        });

        return { opacity, transform: [{ translateX }] };
    }
})
});
robocub
  • 259
  • 2
  • 10
  • Be careful: If you follow the getting started guide of react-navigation's docs, you will end up using NativeStackNavigator (and not StackNavigator) and transitionConfig will not work in that case. I've explained the problem in this answer https://stackoverflow.com/a/74739666/997716 – Apperside Dec 09 '22 at 06:42
8

For StackNavigatoin 6.x.x

Just import

import { TransitionPresets } from '@react-navigation/stack';

Then create a config:

const screenOptionStyle = {
  // headerShown: false,  
  ...TransitionPresets.SlideFromRightIOS,
}; 

And finally just assign them to the Stack Navigator Screen Options:

<Stack.Navigator 
     screenOptions={screenOptionStyle}
    > 

      <Stack.Screen 
      ...
      ...
Lonare
  • 3,581
  • 1
  • 41
  • 45
  • it will not work if you are using createNativeStackNavigator instead of createStackNavigator. If you are following the official docs https://reactnavigation.org/docs/hello-react-navigation most probably you will end up using the former, which does not accept many of the options accepted by the latter. In that case you can pass presentation:"card" and animation: 'slide_from_right' in your Navigator's screenOptions prop – Apperside Dec 01 '22 at 07:53
7

All the above answers are correct, but the solutions work ONLY if you are using createStackNavigator, and not if you are using createNativeStackNavigator; unfortunatelly, if you are following the get started section from react-navigation's docs, you will end up using the latter.

Here you can find a SO question speaking about the differences between the two, but the most relevant one for this questions is that many of the options that your can pass to the former (such as transitionConfig), cannot be passed to the latter.

If you are using createNativeStackNavigator this is how you can do it:

import { createNativeStackNavigator } from '@react-navigation/native-stack'

const StackNavigator = createNativeStackNavigator()

const MyNativeStackNavigator = () =>{
    
    return  <StackNavigator.Navigation
        screenOptions={{
          animation: 'slide_from_right', //<-- this is what will do the trick
          presentation: 'card',
        }}
      >
        {routes}
      </StackNavigator.Navigator>

}
Apperside
  • 3,542
  • 2
  • 38
  • 65
3

you need to import StackViewTransitionConfigs from 'react-navigation-stack' then, override the transitionConfing function.

const myStack = createStackNavigator({
    Screen1,
    Screen2,
    Screen3
},{
    transitionConfig: () => StackViewTransitionConfigs.SlideFromRightIOS
}
Digihive
  • 31
  • 6
2

On @react-navigation/stack component version, the way to do a slide from the right animation is:

<Stack.Navigator
    screenOptions={{
        cardStyleInterpolator: ({index, current, next, layouts: {screen}}) => {
            const translateX = current.progress.interpolate({
                inputRange: [index - 1, index, index + 1],
                outputRange: [screen.width, 0, 0],
            });

            const opacity = next?.progress.interpolate({
                inputRange: [0, 1, 2],
                outputRange: [1, 0, 0],
            });

            return {cardStyle: {opacity, transform: [{translateX}]}};
        },
    }}>
    <Stack.Screen name="MainScreen" component={MainScreen} />
    ...
</Stack.Navigator>
0

Better you can use the react native navigation for this. You can configure your screen using configureScene method. Inside that method use Navigator.SceneConfigs for animating screen. It's work for both android and iOS.

JainZz
  • 602
  • 4
  • 11
0

You can get useful information from index.d.ts file, find the export interface TransitionConfig , then press 'Ctrl' & left_click on NavigationTransitionSpec and NavigationSceneRendererProps, then you can get everything you want.

jiar wang
  • 360
  • 2
  • 12