react-native-reanimated: Incompatibility with React Navigation Native Stack: causes content to be placed under the app bar on Android

Description

When using layout animations in a tabbed/stack view combination using react-navigation’s NativeStack (a fairly common use case), once an animation occurs it will cause the content on top of the screen to be hidden behind the app bar on Android. All tabs that weren’t open before the animation occurred, once opened, will also show this behavior.

Expected behavior

The content should not be hidden by the app bar

Actual behavior & steps to reproduce

Once the layout animation occurs, the app bar on the native stack navigator where the animation is will hide the top of the content. Any tab that has not been opened before the animation occurred, when opened, will show the same issue.

tapping animated tab first and then “other tab” opening “other tab” first and then animated tab

Snack or minimal code example

Demo repository here

The relevant code is this:

import 'react-native-gesture-handler';
import * as React from 'react';
import {StyleSheet, Text, View} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Animated, {BounceIn, BounceOut} from 'react-native-reanimated';

const styles = StyleSheet.create({
  bigText: {
    fontSize: 30,
  },
});

function NormalScreen() {
  return (
    <View>
      <Text style={styles.bigText}>This is a screen without animation.</Text>
    </View>
  );
}
function AnimatedScreen() {
  return (
    <View>
      <Animated.Text
        entering={BounceIn}
        exiting={BounceOut}
        style={styles.bigText}>
        {`Screen with layout animation. Opening this screen will move the content below the app bar.
If this tab is viewed before the "OtherTab", switching to that tab will also show its content under the app bar.
If "OtherTab" is opened first, then only this tab will have the issue.
Once the issue happens, only restarting the app returns it to normal.
        `}
      </Animated.Text>
    </View>
  );
}
const HomeStack = createNativeStackNavigator();
function HomeStackScreen() {
  return (
    <HomeStack.Navigator>
      <HomeStack.Screen name="Home" component={NormalScreen} />
    </HomeStack.Navigator>
  );
}
const AnotherTabStack = createNativeStackNavigator();
function AnotherTabStackScreen() {
  return (
    <AnotherTabStack.Navigator>
      <AnotherTabStack.Screen name="Another" component={NormalScreen} />
    </AnotherTabStack.Navigator>
  );
}

const AnimatedTabStack = createNativeStackNavigator();
function AnimatedTabStackScreen() {
  return (
    <AnimatedTabStack.Navigator>
      <AnimatedTabStack.Screen name="Animated" component={AnimatedScreen} />
    </AnimatedTabStack.Navigator>
  );
}

const Tab = createBottomTabNavigator();
export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator screenOptions={{headerShown: false}}>
        <Tab.Screen name="HomeTab" component={HomeStackScreen} />
        <Tab.Screen name="AnimatedTab" component={AnimatedTabStackScreen} />
        <Tab.Screen name="OtherTab" component={AnotherTabStackScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

Package versions

name version
react-native 0.69.1
react-native-reanimated ^2.9.1
@react-navigation/stack ^6.2.2
@react-navigation/native-stack ^6.7.0
@react-navigation/native ^6.0.11
@react-navigation/bottom-tabs ^6.3.2

Affected platforms

  • [ x ] Android
  • iOS
  • Web

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 12
  • Comments: 16 (2 by maintainers)

Commits related to this issue

Most upvoted comments

Its currently undergoing a rewrite, might be fixed soon

The same issue here. Animated.View component does nothing wrong, but as soon as I include entering or exiting prop the header covers the top content of the screen.

this is caused by the layout animation.

That is correct. Once the entering/exiting animations are removed the issue stops occurring.