问题
I am trying to build an auth flow that has a welcome page and then login or signup depending on the user's case. It is built inside a stack navigator. The first screen has no header but then login and signup do via their screen options.
// AuthNavigator
const AuthStackNavigator = createStackNavigator();
export const AuthNavigator = () => {
return (
<AuthStackNavigator.Navigator
initialRouteName={WELCOME_PAGE.id}
screenOptions={{
headerShown: false,
headerTintColor: colors.primary,
}}
lazy>
<AuthStackNavigator.Screen
name={WELCOME_PAGE.id}
component={WELCOME_PAGE.component}
/>
<AuthStackNavigator.Screen
name={LOGIN_PAGE.id}
component={LOGIN_PAGE.component}
options={LOGIN_PAGE.options}
/>
<AuthStackNavigator.Screen
name={SIGN_UP_PAGE.id}
component={SIGN_UP_PAGE.component}
options={LOGIN_PAGE.options}
/>
</AuthStackNavigator.Navigator>
);
};
This flow, is nested inside a tabNavigator:
// AuthTabNavigator
const AuthTabNavigator =
Platform.OS === 'android'
? createMaterialBottomTabNavigator()
: createBottomTabNavigator();
const RootNavigator = () => {
return (
<AuthTabNavigator.Navigator
activeColor={colors.primary}
inactiveColor="grey"
barStyle={materialBottomNavBackgroundColor}
tabBarOptions={defaultTabNavOptions}>
<AuthTabNavigator.Screen
name={WELCOME_PAGE.id}
component={AuthNavigator}
options={WELCOME_PAGE.options}
/>
</AuthTabNavigator.Navigator>
);
};
export default RootNavigator;
On iOS, things work fine but on Android, It has weird behaviour. When pressing on the input field, the keyboard pushes the bottom bar causing a clunky effect on press but also on dismiss of the field. As if it were recalculating the height every time and repositioning the layout.
In order to make sure it's not coming from my code, I tested again with the snippet from the React Native documentation
I get the following (these are on the Android emulator but I get the same result on my OnePlus android phone)
- base version: https://recordit.co/tcEwDbo1oT
- no header version: https://recordit.co/O4lZ9G83vg
- not nested in a tab navigator: https://recordit.co/uh7mOGlKdk
The only version that works is the one when not nested in the tab navigator so I guess the issue comes from there.
I checked a few solutions but none worked:
- Android manifest
- Issue coming from the header
- Another workaround because of header
I am using React Native CLI:
"react-native": "0.62.2",
"@react-navigation/bottom-tabs": "^5.2.8",
"@react-navigation/drawer": "^5.7.2",
"@react-navigation/material-bottom-tabs": "^5.1.10",
"@react-navigation/native": "^5.1.7",
"@react-navigation/stack": "^5.2.17",
Let me know if you encountered the same issue and found a way to fix it. Thanks in advance.
EDIT: SOLUTION I WENT WITH
On top of the "custom" solution I posted in the comments, after opening an issue on React Navigation repo and checking closed issues, I found that on Android, you might have 2 options:
Either your invert the nesting, see here
Or you can set the behaviour of the keyboardAvoidingView to position on Android and provide a custom Tabbar
https://github.com/react-navigation/react-navigation/issues/7359#issuecomment-545842090
https://stackoverflow.com/a/51169574/11287266
I ended up going with the latter:
const TabBarComponent = props => {
return (
<View collapsable={false}>
<BottomTabBar {...props} />
</View>
);
};
// AuthTabNavigator
const AuthTabNavigator = createBottomTabNavigator();
const RootNavigator = () => {
return (
<AuthTabNavigator.Navigator
activeColor={colors.primary}
inactiveColor="grey"
barStyle={materialBottomNavBackgroundColor}
tabBarOptions={defaultTabNavOptions}
tabBar={props => <TabBarComponent {...props} />}>
<AuthTabNavigator.Screen
name={WELCOME_PAGE.id}
component={AuthNavigator}
options={WELCOME_PAGE.options}
/>
</AuthTabNavigator.Navigator>
);
};
export default RootNavigator;
<KeyboardAvoidingView
contentContainerStyle={{ flexGrow: 1 }}
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'position'}
keyboardVerticalOffset={Platform.OS === 'android' ? -50 : 25}>
来源:https://stackoverflow.com/questions/61856752/react-native-android-keyboardavoidingview-in-stacknavigator-within-a-tabnavi