I am new to react-native, and I’m trying to design a header for a screen that incorporates a back button, a title, and two tabs. While I have a bottom tab layout that applies to all my screens, I simply want to create a top tab layout that can be nested within the current screen I am on.
My problem is rather weird, if I do not nest the Tab.navigator within my header view, the tabs render just fine, although there is a blank space in between. It is why I am trying to nest my tabs within the header. However, when I attempt to do so, the rendering gets weird, with the tabs extending past the size of the screen?
For example, when I use alignItems: ‘center’ to style my header view, it results in the first imagethe two tabs are split in half. If I try alignItems: ‘flex-start’, only the left tab is shown, while if I try alignItems: ‘flex-end’, only the right tab is shown . Notably, if I do not use alignItems, the tabs do not show up at all. Below is my code for the screen, could someone explain why such an error occurs, and how I can fix it?
import { View, Text, Button, StyleSheet, TextInput, ScrollView, TouchableOpacity, Platform } from 'react-native';
import { useNavigation, NavigationContainer } from '@react-navigation/native';
import { HeaderBackButton } from '@react-navigation/elements';
import DateTimePicker, { DateTimePickerEvent, Event } from '@react-native-community/datetimepicker';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
const Tab = createMaterialTopTabNavigator();
function FirstTab() {
return (
<View style={{...styles.container}}>
<Text>First Tab Content</Text>
<View>
<Text style={styles.descText}>Title</Text>
<TextInput style={styles.inputText}></TextInput>
<Text style={styles.descText}>Paid By</Text>
<TextInput style={styles.inputText}></TextInput>
</View>
</View>
);
}
function SecondTab() {
return (
<View style={styles.container}>
<Text>Second Tab Content</Text>
</View>
);
}
export default function group() {
const navigation = useNavigation();
const handleBackButtonPress = () => {
navigation.goBack();
};
return (
<View style={styles.container}>
<View style={styles.header}>
<View style={{flexDirection: 'row', borderWidth: 2}}>
<HeaderBackButton tintColor='white' onPress={handleBackButtonPress} />
<Text style={styles.headerText}>#Group-Name-Here</Text>
</View>
<View>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarLabelStyle: { fontSize: 16, color: 'white' },
tabBarStyle: { backgroundColor: 'purple' },
tabBarIndicatorStyle: { backgroundColor: 'white' },
tabBarLabel: ({ focused }) => {
let label;
if (route.name === 'FirstTab') {
label = 'First';
} else if (route.name === 'SecondTab') {
label = 'Second';
}
return <Text style={{ color: focused ? 'white' : 'gray' }}>{label}</Text>;
},
})}>
<Tab.Screen name="FirstTab" component={FirstTab} options={{ tabBarLabel: 'Bills' }} />
<Tab.Screen name="SecondTab" component={SecondTab} options={{ tabBarLabel: 'Balances' }} />
</Tab.Navigator>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'black',
},
header: {
backgroundColor: 'purple',
flexDirection: 'column',
alignItems: 'center', //THE LINE THAT CAUSES WEIRD ISSUES?
padding: 8,
marginBottom: 12,
marginTop: 50,
},
headerText: {
// textAlign: 'center',
fontSize: 24,
color: 'white',
marginLeft: 8,
},
descText: {
color: 'grey',
fontSize: 16,
padding: 8,
marginHorizontal: 24,
},
inputText: {
color: 'white',
paddingHorizontal: 8,
fontSize: 20,
marginHorizontal: 24,
borderBottomColor: 'purple',
borderWidth: 2,
marginBottom: 8,
},
});
YF Leong is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.