How do I animate React Navigation transitions using createBottomTabNavigator?
Asked Answered
C
10

Just create an Animated.View and attach that to your screens.

const FadeHomeScreen = (props) => (
  <FadeInView>
    <HomeScreen {...props} />
  </FadeInView>
);

then use this for Tab.Screen

<Tab.Screen name="Home" component={FadeHomeScreen} />

and just add unmountOnBlur: true in the screenOptions

const screenOptions = {
    unmountOnBlur: true,
    headerShown: false,
};

<Tab.Navigator {...{ screenOptions }}>

Code: https://snack.expo.dev/@fanish/native-stack-navigator-%7C-react-navigation

You could also use react-native-reanimated to create <FadeInView /> component

Croaky answered 17/9, 2021 at 18:51 Comment(7)
Thank you so much. However, is there a way to maintain state on the faded page? Enabling unmountOnBlur causes the user to lose all navigation history. Is there an approach that enables the same behavior but retains all state logic?Gawky
Yes, there is a way to do that but you will have to use focus event listener. Triggering an action with a 'focus' event listener and call FadeAnimation.Croaky
made it work using useFocusEffect hook snack.expo.dev/@pedrosousa/fade-animation-between-bottom-tabs. Now the next step is actually implementing a fade animation that transitions between screen contents and not between a rootviewbackground (in this case a blank white screen)Gawky
Add this property <Tab.Navigator {...{ screenOptions,sceneContainerStyle }}> and const sceneContainerStyle={ backgroundColor:'#95a5a6' } You won't see the white screen.Croaky
Thank you man! You saved me bunch of timeSpeech
why do you set unnmountOnBlur to true exactly?Foreboding
This is a late reply, but @VariabileAleatoria, it is most likely due to the fact that when a navigation screen mounts it does not unmount until the app is closed. Thus unmountOnBlur is required for triggering the fade-out animation on un-mount so that it can fade back in on re-mount. I assume something similar could be implemented using React Navigation's useFocusEffect or attaching a listener to the navigation object.Confrere
D
0

Wrap Screen components into FadeView compoent and don't forget to add unmountOnBlur: true in the screenOptions

fade-view.tsx

import { cn } from "@/lib/utils";
import { View } from "react-native";
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";

type FadeViewProps = {
  children: React.ReactNode;
  className?: string;
};
export default function FadeView({ children, className }: FadeViewProps) {
  return (
    <View className={cn("flex-1 bg-white")}>
      <Animated.View
        className={cn("flex-1", className)}
        entering={FadeIn}
        exiting={FadeOut}
      >
        {children}
      </Animated.View>
    </View>
  );
}

index.tsx

...
import FadeView from "@/components/animation/fade-view";

export default function Index() {
  return (
    <FadeView>
     ...
    </FadeView>
  );
}

I just wrapped every component except _layout inside (tabs) into

enter image description here

Dellinger answered 11/6 at 23:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.