Is there any way I can place the TabBar over my header - react-native

I had an idea in my design but making it proved harder than I thought. The design is as follows:
The tabbar here is made with 'createMaterialTopTabNavigator'.
My idea was that the gradient part will be the header so it won't move when navigating from INFO to PHOTOS. I am able the screen the way it looks in the picture above except for the TopTabNavigator overlapping the header. It looks as follows:
I do understand why this is happening since the topTabNavigator is inside of the stackNavigator and thus the header will always be on top. The thing is that I want the gradient part to stay in place when swiping left or right through the topTabNavigator.
The profile Stack Screen:
const ProfileStackScreen = ({ navigation }) => {
return (
<ProfileStack.Navigator>
<ProfileStack.Screen name="Profile" component={ProfileTabScreen} options={{
header: () => ( <ProfileHeader onPress={() => {navigation.openDrawer()}} />)
}} />
</ProfileStack.Navigator>
);
};
The header:
const ProfileHeader = (props) => {
return (
<LinearGradient colors={[color1, color2]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={{
width: '100%,
alignItems: 'center',
paddingVertical: 50,
}}>
<View style={{width: '100%}}>
<View style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 20,
width: '100%',
}}>
<TouchableOpacity><Icon /></TouchableOpacity>
<TouchableOpacity><Text>Edit profile</Text></TouchableOpacity>
</View>
</View>
<Image style={{height: 115, width: 115, borderRadius: 100}} source={require('../path/img.jpg')} />
</LinearGradient>
);
}

Related

React Native: backgroundColor in View-Component is not working

I started to learn React Native two days ago and I am wondering why the backgroundColor "yellow" and "green" are not working. My whole screen is white. I thought that, because I used 3 times a flex: 0.5, that the screen is devided in 3 parts with different backgroundColors. What is the problem here? The dividing in 3 parts seems to work, because the text is, image and button are on the top 1/3, but the second 1/3 and third 1/3 are white.
Here is the code:
console.log("App executed");
return(
<View style={styles.viewStyles}>
<Text style={styles.textStyles} onPress={() => console.log("Text clicked")}>Beispielfüroben</Text>
<TouchableOpacity onPress={() => console.log("Bild clicked")}>
<Image source={require("./assets/books.jpg")} style={styles.logoStyles}></Image>
</TouchableOpacity>
<Button
style={styles.buttonStyles}
title= "Beispielbutton"
onPress={() => Alert.alert("Hallo", "I bims 1 clown",[{text: "hallo", onPress: () => console.log("Hallo clicked")}, {text: "no"}])}
></Button>
<View style={{backgroundColor: "yellow", flex: 0.5}}/>
<View style={{backgroundColor: "green", flex: 0.5}}/>
</View>
)
};
const styles = StyleSheet.create({
viewStyles: {
backgroundColor: "white",
flex: 0.5,
alignItems: 'center',
justifyContent: 'center'
},
Can you help me?
Thanks a lot :)
The issue here is that a View, which does not contain any children, won't fill any space unless we are telling it to do so.
The flex property will only
define how your items are going to “fill” over the available space along your main axis. Space will be divided according to each element's flex property.
Hence, let your Views occupy 100% of the available height and width. If the flex property is equal for both views, then the available space will be filled equally.
If you want to let the text, button and touchable opacity, occupy 1/3 of the screen, then you need to put them inside the same parent view with a flex of 1 as well and provide the same height and width percentage (100 in both cases).
export default function App() {
return (
<SafeAreaView style={styles.viewStyles}>
<View style={{ width: '100%', height: '100%', flex: 1, alignItems: 'center' }}>
<Text onPress={() => console.log('Text clicked')}>Beispielfüroben</Text>
<TouchableOpacity onPress={() => console.log('Bild clicked')}>
<Image
source={require('./assets/snack-icon.png')}
style={styles.logoStyles}></Image>
</TouchableOpacity>
<Button
title="Beispielbutton"
onPress={() =>
Alert.alert('Hallo', 'I bims 1 clown', [
{ text: 'hallo', onPress: () => console.log('Hallo clicked') },
{ text: 'no' },
])
}></Button>
</View>
<View
style={{
backgroundColor: 'yellow',
flex: 1,
width: '100%',
height: '100%',
}}
/>
<View
style={{
backgroundColor: 'green',
flex: 1,
width: '100%',
height: '100%',
}}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
viewStyles: {
backgroundColor: 'white',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
logoStyles: {
width: 24,
height: 24,
},
});
The result is as follows
Here is a snack.

tabBarButton style not applying react-nav-6

I would like to change the styling of a main button. Although this code is not working. I would like the styling to not be affected by the nav bar height. Here is code
const CircleButton = ({ children, onPress }) => (
<TouchableOpacity onPress={onPress} style={{
top: -30,
justifyContent: 'center',
alignItems: 'center',
...style.shadow
}}>
<View style={{
width: 70,
height: 70,
borderRadius: 35,
backgroundColor: 'yellow',
}}>
{children}
</View>
</TouchableOpacity>
)
<bTabs.Navigator
screenOptions={{ tabBarLabel: false, }}
barStyle={{
position: 'absolute',
bottom: 25,
left: 20,
right: 20,
elevation: 0,
backgroundColor: theme.nav.backgroundColor,
borderRadius: 10,
height: 50,
...style.shadow
}}
>
<bTabs.Screen name="Create" component={CreateContent} options=
{{
tabBarIcon: ({ focused }) => (
<View>
<Icon name='plus' size={25} color={focused ? theme.mainColor : theme.secondaryBGColor} />
</View>
),
tabBarButton: (...props) => <CircleButton {...props} onPress={() => console.log('t')} />,
}}
/>
Also note i have tried using tabBarButton: (...props) => (<CircleButton {...props} onPress={() => console.log('t')} />), and with {}
Please ignore syntax. Thank you

react-native custom header navigator has unwanted margins

I have drawer and stack navigator. I disabled header of drawer and stack navigators. And create my own header component but I cannot rid of the edge margins of my custom header component.
[Screenshot]
https://i.stack.imgur.com/5jWv3.png
const styles = StyleSheet.create({
header: {
backgroundColor: 'purple',
width: '100%',
height: '100%',
flexDirection: 'row',
alignItems: 'center',
},
headerText: {
fontWeight: 'bold',
fontSize: 21,
letterSpacing: 1,
paddingLeft: 45,
paddingBottom: 2,
},
icon: {
fontSize: 30,
color:"white",
position: 'absolute',
zIndex: 3,
}});
 
return (
<View style={styles.header}>
<View style={styles.header}>
<MaterialIcons style={styles.icon} name="menu" onPress={openMenu}/>
<Text style={styles.headerText}>{titleName}</Text>
</View>
</View>
)
This is your header Component. Have you checked if the Main Container does not have a paddingHorizontal in the Screen?
Solution #1
Change:
return (
<View style={styles.header}>
<View style={styles.header}>
<MaterialIcons style={styles.icon} name="menu" onPress={openMenu}/>
<Text style={styles.headerText}>{titleName}</Text>
</View>
</View>
)
to:
return (
<View style={styles.header}>
<MaterialIcons style={styles.icon} name="menu" onPress={openMenu}/>
<Text style={styles.headerText}>{titleName}</Text>
</View>
)
Solution #2
import {Dimensions} from 'react-native'
let width=Dimensions.get('screen').width
let height=Dimensions.get('screen').height
then:
const styles = StyleSheet.create({
header: {
backgroundColor: 'purple',
width: width,
height: height,
flexDirection: 'row',
alignItems: 'center',
},
})
I fixed the issue with opening the app on web to see styles of parent the element. In this case my parent element is the <Stack.screen> home tab.
I just checked the styles on web which is
marginLeft: 16,
marginRight: 16,
maxWidth: 470,
and override these styles with
marginLeft: 0,
marginRight: 0,
maxWidth: '100%',
screenshot of the solution result
<Stack.screen
options={{headerBackgroundContainerStyle: {
marginLeft: 0,
marginRight: 0,
maxWidth: '100%'
}
}}
/>

React Navigation 5 Header Options

How Do I set the Header right property on the <Stack.Navigator> ? I tried it with screenOptions but it is not rendering the headerRight Content on the right of header. I could set it on the parent Navigation Component which is rendering this custom component but in there I am not able to access the navigation prop. Could anyone please help me? Thank You
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen options={options3} name="SellerStackNavigator"
component={SellerStackNavigator} />
</Stack.Navigator>
</NavigationContainer>
const SellerStack = createStackNavigator();
const SellerStackNavigator = ({ navigation, route }) => {
<SellerStack.Navigator
screenOptions={({ route, navigation }) => ({
headerRight: () => (
<View style={{
flexDirection: 'row',
marginRight: 10,
}}>
<TouchableOpacity style={{
backgroundColor: '#fff',
borderRadius: 20,
marginRight: 10,
marginTop: 10,
height: 40,
width: 40,
alignItems: 'center',
justifyContent: 'center',
elevation: 2,
paddingLeft: 10,
}}>
<Image style={{
resizeMode: 'contain',
alignSelf: 'center',
borderWidth: 1,
marginRight: 10,
tintColor: '#000',
width: 15,
height: 18,
}} source={Images.searchImage}/>
</TouchableOpacity>
</View>
)
})}>
.
.
.
.
.
</SellerStack.Navigator>
}
I used more or less your code and is working for me, so if you can make a expo I can check what is really happening https://snack.expo.io/#anthowm/headerright
Anyways you can accesss your navigation from anywhere with useNavigation hook
function MyBackButton() {
const navigation = useNavigation();
return (
<Button
title="Back"
onPress={() => {
navigation.goBack();
}}
/>
);
}
You can do access to it
<NavigationContainer>
{(route, navigation) => {
return <Stack.Navigator>
<Stack.Screen options={options3} name="SellerStackNavigator"
component={SellerStackNavigator} />
</Stack.Navigator>}}
</NavigationContainer>

tab bar icons not perfectly centered when screen changes

I have a issue with my costume tab bar and that is when I select other screens icons lose their position a little bit and shift to for example right. for better understanding consider these two images:
you can see this compass icon is not centered perfectly:
but when I tap on screen this become perfectly centered:
here's my styles on custom bottom tab bar :
const TabComponent = ({label, accessibilityState, onPress}) => {
const focused = accessibilityState.selected;
const icon = focused ? ICONS[`${label}Active`] : ICONS[label]
return (
<TouchableWithoutFeedback onPress={onPress}>
<View focused={focused} style={[styles.container, focused ? styles.focused : null]}>
<Image style={styles.icon} source={icon} />
</View>
</TouchableWithoutFeedback>
)
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 20
},
focused: {
backgroundColor: '#3170FF',
borderRadius: 25,
width: 46,
height: 75,
position: 'relative',
bottom: 20
},
icon: {
width: 24,
height: 24,
}
})
and below is my styles on bottom tab itself:
<Tab.Navigator tabBarOptions={{
style: {
borderTopLeftRadius: 23,
borderTopRightRadius: 23,
height: 64,
alignItems: 'center',
}
}} >
<Tab.Screen name="Home" component={Home} options={{
tabBarButton: (props) => <TabComponent label='home' {...props} />,
}}/>
...
how can I fix this issue? any help would be great.