Reputation: 359
I have a single application which includes only navigation packages. On IOS, all is fine but on Android, header and/or bottom tabbar seems like jumping (maybe recalculating their positions). This happens only when I use navigation components and only when app is just launched. Is there anyone faced same problem?
Thanks in advance.
Packages:
"@react-native-community/masked-view": "^0.1.10",
"@react-navigation/bottom-tabs": "^5.6.1",
"@react-navigation/native": "^5.6.1",
"@react-navigation/stack": "^5.6.2",
"react": "16.11.0",
"react-native": "0.62.2",
"react-native-gesture-handler": "^1.6.1",
"react-native-reanimated": "^1.9.0",
"react-native-safe-area-context": "^3.0.7",
"react-native-screens": "^2.9.0"
This is the whole app:
import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function DetailsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
const HomeStack = createStackNavigator();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
</HomeStack.Navigator>
);
}
const SettingsStack = createStackNavigator();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
Upvotes: 22
Views: 7980
Reputation: 59
give this
navigationOptions: {
headerShown: true,
safeAreaInsets: {
top: 0,
bottom: 0,
left: 0,
right: 0,
},
},
if you are using react-navigation 4x
Upvotes: 0
Reputation: 9650
I was struggling with this exact bug for a while. I've finally been able to find a workaround.
It seems that all the ReactNavigation navigators (eg Tab and Stack) will by default accommodate safe areas. This is mentioned in this page: https://reactnavigation.org/docs/bottom-tab-navigator/
By default, the device's safe area insets are automatically detected
So it seems the behaviour we're seeing is due to this. It's not clear why ReactNavigation has buggy "safe area" logic, but the workaround is to disable that.
The workaround is similar to what @Arun Girivasan has suggested, with a couple extra steps:
SafeAreaProvider
and SafeAreaView
safeAreaInsets
to be 0 for all directions:<Tab.Navigator
initialRouteName="AppDashboard"
tabBarOptions={{
safeAreaInsets: {
top: 0,
bottom: 0,
left: 0,
right: 0,
}
}}
>
safeAreaInsets
for your stack navigators.With these changes I'm no longer seeing the tab bar height jump AND i'm no longer seeing the stack header jumping. Basically this workaround resolves all UI glitches for me.
Upvotes: 11
Reputation: 11
same thing happend to me on @react-navigation/bottom-tabs i just removed paddingBottom and padding top from "tabstyle" and pasted in "style" this solved the issue
BEFORE:
tabBarOptions={{
keyboardHidesTabBar: true,
activeTintColor: COLOR.white,
style: {
backgroundColor: COLOR.primary,
height: responsiveHeight(7),
},
tabStyle: {
paddingBottom: responsiveHeight(0.5),
paddingTop: responsiveHeight(0.5),
},
}}
AFTER:
tabBarOptions={{
keyboardHidesTabBar: true,
activeTintColor: COLOR.white,
style: {
backgroundColor: COLOR.primary,
height: responsiveHeight(7),
paddingBottom: responsiveHeight(0.5),
paddingTop: responsiveHeight(0.5),
},
}}
...
i hope it helps :)
Upvotes: 1
Reputation: 602
I fixed this problem by using SafeAreaProvider. You should add SafeAreaProvider
in your app root component and use SafeAreaView
as the root component of your page. Also check the import statement of SafeAreaView
, react-native
also has SafeAreaView
but that component only supports iOS 10+ .
Upvotes: 23