How can I change the background color of the full header in React Native - react-native

I'm using the Header component of react-native-elements, which has a blue background by default. I changed it into green, but the upper piece of the header (with the information of your phone, like hour and wifi) stays in blue.
Header in two colors
Can someone explain me how to modify this part of the header so all of it would be in light green please ?
Here is my App() code :
export default function App() {
const Stack = createNativeStackNavigator();
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Connexion"
screenOptions={{ headerShown: false }}>
<Stack.Screen name="Connexion" component={ConnexionScreen} />
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
And this is my page code :
import React from 'react';
import { View, Text, Button } from 'react-native';
import { Header } from 'react-native-elements';
export default function ConnexionScreen({ navigation }) {
return (
<View style={{ flex: 1 }}>
<Header
containerStyle={{ backgroundColor: '#B5F7D3' }}
leftComponent={{
icon: 'menu',
color: '#fff',
iconStyle: { color: '#fff' },
}}
centerComponent={{ text: 'NURISENS', style: { color: '#fff' } }}
rightComponent={{ icon: 'home', color: '#fff' }}
barStyle="light-content"
/>
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'green',
}}>
<Text>Connexion Screen</Text>
<Button
title="Valider la connexion"
onPress={() => navigation.navigate('Home')}
/>
</View>
</View>
);
}

This is your StatusBar. Try to add back backgroundColor: "#B5F7D3" prop to your Header component.
If the statusBar's color does not change then add the StatusBar Component like so:
import { StatusBar } from 'react-native'
and in the return statement do implement it like this before the Header component.
<StatusBar barStyle = "light-content" hidden = {false} backgroundColor = "#B5F7D3" translucent = {true}/>
Hope this works for you.

Try this
<Header backgroundColor="#B5F7D3" />

Related

How to make headerTitle to fit into headerBackground with react navigation?

I am using the react navigation library with react native, I want to create a custom header by using the headerBackground and headerTitle screen options.
I need a robust way for the headerTitle component to use all the available space, but remains inside the limits of the screen.
So far I have (Snack link):
function App(): JSX.Element {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
options={{
headerBackground: () => (
<View
style={{
flex: 1,
backgroundColor: 'red',
borderColor: 'green',
borderWidth: 4,
}}
/>
),
headerTitle: props => (
<View
style={{
backgroundColor: 'blue',
flex: 1,
}}>
<Text>Header Title</Text>
</View>
),
}}>
{() => <SafeAreaView />}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
);
}
Note I have inlined styles and other bad practices just to make the code shorter for this question.
The results is the following:
Note how the headerTitle component grows without limits.
Is there a robust way to deal with this issue ? Note I am trying to avoid getting/using the dimensions of the device, as in the header can be other content such as backButton, or other options buttons on the right side.
Thanks in advance.
here is code example you can see to run this code may be this will help you:)
App.js
import * as React from 'react';
import {
Button,
View,
Text,
ImageBackground,
StyleSheet,
TouchableOpacity,
Image
} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
const image = { uri: 'https://reactjs.org/logo-og.png' };
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function DetailsScreen({ navigation }) {
return (
<View style={{}}>
<ImageBackground source={image} style={styles.image}>
<TouchableOpacity
onPress={()=>navigation.navigate("Home")}
>
<Image source={{uri:"https://cdn-icons-png.flaticon.com/128/189/189254.png"}} style={{width:30,height:30,marginLeft:10,marginTop:20}}/>
<Text style={{fontSize:30 ,color:'white',textAlign:'center',fontWeight:'bold',marginTop:-40}}> hello world</Text>
</TouchableOpacity>
</ImageBackground>
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerShown: false,
}}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
image: {
width: "100%",
height: 60,
},
text: {
color: 'white',
fontSize: 42,
lineHeight: 84,
fontWeight: 'bold',
backgroundColor: '#000000c0',
},
});
export default App;

How to add an indicator under the active bottom tab?

I need to add an indicator for the active tab I tried to add a borderBottom with tabStyle but we can't check focused with that.
Using react-navigation v5 and createBottomTabNavigator for bottom tabs.
Here's my code:
<BottomTab.Navigator
tabBarOptions={{
activeTintColor: colors.brown,
labelPosition: 'below-icon',
}}>
<BottomTab.Screen
name="Home"
component={HomeTabNav}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({focused}) => {
return focused ? (
<HomeSelectedIcon height={ms(24)} width={ms(24)} />
) : (
<HomeIcon height={ms(24)} width={ms(24)} />
);
},
}}
/>
...
</BottomTab.Navigator>
);
};
Thanks in advance!
I figured it out myself by making a custom tabbar icon if someone needs to achieve this using the bottom-tab bar only.
Here's the code.
<BottomTab.Navigator
tabBarOptions={{
activeTintColor: colors.brown,
showLabel: false,
tabStyle: styles.tabStyle,
style: styles.tabContainerStyle,
}}>
<BottomTab.Screen
name="Home"
component={HomeTabNav}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({focused}) => {
return focused ? (
<View style={styles.labelFocusedContainer}>
<HomeSelectedIcon height={24} width={24} />
<Text style={styles.labelFocusedStyle}>Home</Text>
</View>
) : (
<View style={styles.labelContainer}>
<HomeIcon height={24} width={24} />
<Text style={styles.labelStyle}>Home</Text>
</View>
);
},
}}
/>
...
</BottomTab.Navigator>
const styles = StyleSheet.create({
labelContainer: {
alignItems: 'center',
width: '100%',
},
labelFocusedContainer: {
alignItems: 'center',
width: '100%',
borderBottomWidth: 3,
borderBottomColor: colors.brown,
},
labelFocusedStyle: {
textAlign: 'center',
marginVertical: 8,
color: colors.brown,
backgroundColor: 'transparent',
fontSize: 10,
},
labelStyle: {
textAlign: 'center',
marginVertical: 8,
color: colors.veryDarkgray,
backgroundColor: 'transparent',
fontSize: 10,
},
});
But the best and easy way to do this is by using createMaterialTopTabNavigator and using these props.
tabBarPosition="bottom"
tabBarOptions={{
showIcon: true,
pressOpacity: 1,
iconStyle: styles.iconStyle,
showLabel: true,
activeTintColor: colors.brown,
indicatorStyle: {
borderWidth: 2,
borderColor: colors.brown,
},
This does not seem to be possible / easily achievable with bottom-tabs, but you could use the material version - #react-navigation/material-top-tabs and configure it to match your needs, specifically using tabBarPosition="bottom" and tabBarOptions={{ indicatorStyle: { backgroundColor } }}.
You can check more options in the docs: https://reactnavigation.org/docs/material-top-tab-navigator/#tabbaroptions
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
const Tabs = createMaterialTopTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tabs.Navigator tabBarPosition="bottom" tabBarOptions={{ indicatorStyle: { backgroundColor: 'red' } }}>
<Tabs.Screen name="screen 1" component={View} />
<Tabs.Screen name="screen 2" component={View} />
</Tabs.Navigator>
</NavigationContainer>
);
}
The best answer would be to use the tabBarButton prop to override and add your own custom styles to the container of the tab button.
https://reactnavigation.org/docs/bottom-tab-navigator#tabbarbutton
const CustomTabButton = (props) => (
<Pressable
{...props}
style={
props.accessibilityState.selected
? [props.style, styles.activeTab]
: props.style
}
/>
)
styles.activeTab is the custom style you want to add, be careful to spread the props.style to get the default styles from the library like width, padding, height etc
props.accessibilityState.selected will add styles according to condition if you want styles for all the tabs you can remove the condition.
Inside screeenOptions prop on navigator or the option props of each screen.
tabBarButton: CustomTabButton
Using material top tab is not a good solution because it does not support well with a keyboard. But bottom tabs do work well with the keyboard.

How to always Show Bottom Tabs Label in React Native Navigation V5?

return (
<Tab.Navigator
barStyle={{backgroundColor: '#F2F2F2'}}
initialRouteName="Catalog">
<Tab.Screen
name="Settings"
options={{
tabBarLabel: 'Alterações',
title: 'Configurações',
tabBarIcon: ({color}) => (
<MaterialCommunityIcons name="cog" color="#000" size={22} />
),
}}>
{(props) => (
<Settings
{...props}
params={{
cpf: params.cpf ? params.cpf : cpf,
}}
/>
)}
</Tab.Screen>
<Tab.Screen
name="Catalog"
options={{
tabBarVisible: false,
title: 'Ofertas',
}}>
{(props) => (
<Catalog
{...props}
params={{
pracaId: params.pracaId ? params.pracaId : pracaId,
}}
/>
)}
</Tab.Screen>
[...]
</Tab.Navigator>
);
The documentations says to use the titleDisplayMode but where? when? I only find solution for older versions. I need it to v5.
Please, can some one help me?
I have include some part of my code to understend how I'm using the lib
There is a shifting prop that you can put to false in your navigator :
<Tab.Navigator
barStyle={{backgroundColor: '#F2F2F2'}}
initialRouteName="Catalog"
shifting={false}
>
.....
Whether the shifting style is used, the active tab icon shifts up to show the label and the inactive tabs won't have a label.
By default, this is true when you have more than 3 tabs. Pass shifting={false} to explicitly disable this animation, or shifting={true} to always use this animation.
https://reactnavigation.org/docs/5.x/material-bottom-tab-navigator#shifting
I have created this example where the HomeScreen always hide the bottom tab and the SettingsStack always show the bottom tab automatically. The key point is basically these lines of code, one have just a screen and the other one have a StackNavigator:
<Tab.Screen name="HomeScreen" component={HomeScreen} />
<Tab.Screen name="SettingsStack" component={SettingsStack} />
This example is similar to the one in the docs https://reactnavigation.org/docs/hiding-tabbar-in-screens/, but with more components.
The code below is in snack, check if this helps you:
https://snack.expo.io/#ronicesarrc/react-navigation-hiding-showing-bottom-tab-navigator
import React from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs';
function SettingsInternalScreen() {
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'orange',
}}>
<Text>SettingsInternalScreen!</Text>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
}}>
<TouchableOpacity
style={{ backgroundColor: 'orange', padding: 16 }}
onPress={() => navigation.navigate('SettingsInternalScreen')}>
<Text>Go to Screen showing bottom tab</Text>
</TouchableOpacity>
</View>
);
}
const SettingStack = createStackNavigator();
function SettingsStack() {
return (
<SettingStack.Navigator>
<SettingStack.Screen name="SettingsScreen" component={SettingsScreen} />
<SettingStack.Screen
name="SettingsInternalScreen"
component={SettingsInternalScreen}
/>
</SettingStack.Navigator>
);
}
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
style={{ backgroundColor: 'gray', padding: 16 }}
onPress={() => navigation.navigate('HomeInternalScreen')}>
<Text>Go to Screen hidding bottom tab</Text>
</TouchableOpacity>
</View>
);
}
function HomeInternalScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>HomeInternalScreen!</Text>
</View>
);
}
const Tab = createMaterialBottomTabNavigator();
const Tabs: React.FC = () => {
return (
<Tab.Navigator>
<Tab.Screen name="HomeScreen" component={HomeScreen} />
<Tab.Screen name="SettingsStack" component={SettingsStack} />
</Tab.Navigator>
);
};
const MainStack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<MainStack.Navigator headerMode="none">
<MainStack.Screen name={'Tabs'} component={Tabs} />
<MainStack.Screen
name={"HomeInternalScreen"}
component={HomeInternalScreen}
/>
</MainStack.Navigator>
</NavigationContainer>
);
}

React native navigation 5 stackNavigator not working on production

I'm using ReactNavigation for tab navigator and stackNavigator. It's working 100% on development, mode but the stacNavigator is not working on production builds. The app is not crashing, it just isn’t navigating through pages. But the tab navigator is working fine.
Anyone having this issue?
I have opened an issue.
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import AdminHome from './AdminScr/AdminHome
import AdmLogin from './AdminScr/AdminLogin';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function App() {
return (
<View style={styles.container} >
<Stack.Navigator style={{ backgroundColor: '#e91e63' }}>
<Stack.Screen name="AdmHome" component={AdminHome} options={{
title: 'Admin Home',
headerStyle: {
//backgroundColor: '#1e90ff',
backgroundColor: '#E66E2F'
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
/>
<Stack.Screen name="AdmLogin" component={AdmLogin} options={{
title: 'Admin Login',
headerStyle: {
backgroundColor: '#E66E2F',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
/>
</Stack.Navigator>
</View>
);
}
export default () => {
return (
<NavigationContainer>
<App />
</NavigationContainer>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#e91e63',
},
});
Calling in AdminLogin.js page.
//For Arrow Function
const AdmLogin=(props)=> { //Passing props in fat area like (props).
return (
<View>
<TouchableOpacity style={styles.signinbutton} onPress={() => props.navigation.navigate("AdmHome")} >
<Text style={styles.buttonText}> Sign In</Text>
</TouchableOpacity>
</View>
)}
//For Class Method
<TouchableOpacity style={styles.signinbutton} onPress={() => this.props.navigation.navigate("AdmHome")} >
<Text style={styles.buttonText}> Sign In</Text>
</TouchableOpacity>

Adding a custom 'Add' button to createMaterialBottomTabNavigator in react navigation 5

I'm making a project (react native, expo, react navigation 5) where I wanted to add a custom 'add' button to the bottom tabs, but since...
A navigator can only contain 'Screen' components as its direct
children
...I needed to find a way to pass my custom component.
Seemed easy enough, I mean there are docs:
https://reactnavigation.org/docs/material-bottom-tab-navigator
https://reactnavigation.org/docs/bottom-tab-navigator
https://reactnavigation.org/docs/custom-navigators/
...but in looking at these and the questions from others I either only found muy complicado examples or examples of how to achieve this in earlier versions.
In the end I found a simple solution that so far works like a charm (fully grateful to any suggestions as to why this might be a terrible idea).
Figured I post my solution if anyone is in a similar pickle. See answer below.
Place the component outside the navigator, and position it above the tabs with css. Adjust the icons of the tabs to the left and right as seen in the example.
Like I said above, suggestions on how to achieve this in a different way warmly welcome, but haven't encountered any issues yet (knock on wood).
Here's what it looks like:
And here's the bunny:
import React from 'react';
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs';
import { Ionicons, MaterialIcons, FontAwesome } from '#expo/vector-icons';
import AddButton from '../../components/UI/AddButton';
import SpotlightProductsScreen from './SpotlightProductsScreen';
import ProductsScreen from './ProductsScreen';
import UserSpotlightScreen from './../user/UserSpotlightScreen';
import UserProductsScreen from './../user/UserProductsScreen';
const ProductsOverviewScreen = props => {
const Tab = createMaterialBottomTabNavigator();
return (
<>
<AddButton
navigation={props.navigation}
style={{
position: 'absolute',
zIndex: 99,
bottom: 5,
alignSelf: 'center',
shadowColor: 'black',
shadowOpacity: 0.15,
shadowOffset: { width: 0, height: 2 },
shadowRadius: 8,
elevation: 3 //Because shadow only work on iOS, elevation is same thing but for android.
}}
/>
<Tab.Navigator
initialRouteName="Spotlight"
labeled={false}
shifting={true}
activeColor="#f0edf6"
inactiveColor="#3e2465"
barStyle={{ backgroundColor: 'rgba(127,63,191,.9)' }}
>
<Tab.Screen
name="Spotlight"
component={SpotlightProductsScreen}
options={{
tabBarIcon: ({ color }) => (
<Ionicons
name={
Platform.OS === 'android'
? 'md-notifications'
: 'ios-notifications'
}
color={color}
size={27}
style={{
marginLeft: -35
}}
/>
)
}}
/>
<Tab.Screen
name="Förråd"
component={ProductsScreen}
options={{
tabBarIcon: ({ color }) => (
<MaterialIcons
name={'file-download'}
color={color}
size={27}
style={{
marginLeft: -70
}}
/>
)
}}
/>
<Tab.Screen
name="Mitt Förråd"
component={UserProductsScreen}
options={{
tabBarIcon: ({ color }) => (
<MaterialIcons
name={'file-upload'}
color={color}
size={30}
style={{
marginRight: -70
}}
/>
)
}}
/>
<Tab.Screen
name="Min Sida"
component={UserSpotlightScreen}
options={{
tabBarBadge: 4,
tabBarIcon: ({ color }) => (
<FontAwesome
name={'user'}
color={color}
size={30}
style={{
marginRight: -35
}}
/>
)
}}
/>
</Tab.Navigator>
</>
);
};
export default ProductsOverviewScreen;
You can try this:
<Tab.Screen
name = "Button"
component={ScanStack}
options={{
tabBarButton:()=>
<View style={{position:'relative',bottom:35,alignItems:'center', justifyContent:'space-around',height:85}}>
<Icon
name="barcode-scan"
type = "material-community"
reverse
color={'yellow'}
reverseColor='black'
containerStyle={{padding:0,margin:0,elevation:5}}
onPress={()=>console.log('Hi')}
size={30}/>
<Text>Scan</Text>
</View>
}}/>
In the component it is necessary to use a valid react-component, I tried to use component={()=>null} but a warn appeared in the console
Result
I had the same problem, I needed to add a custom component, not related with a screen, to the tab navigator and everything I tried it failed. In my case I was trying with createMaterialTopTabNavigator.
Documentation of React Navigation 5 is a little rough and there isn't a lot of examples of React Navigation 5, but after many attempts I could create a custom component and style it myself so I can mix the tabs created by the routes and the custom buttons embedded in the tab navigator.
import * as React from 'react';
import { View } from 'react-native'
import {
NavigationHelpersContext,
useNavigationBuilder,
TabRouter,
TabActions,
createNavigatorFactory,
} from '#react-navigation/native';
import styled from 'styled-components'
import Colors from '../constants/Colors';
const customTabNavigator = ({
initialRouteName,
children,
screenOptions,
tabContainerStyle,
contentStyle,
leftIcon,
rightIcon
}) => {
const { state, navigation, descriptors } = useNavigationBuilder(TabRouter, {
children,
screenOptions,
initialRouteName,
});
return (
<NavigationHelpersContext.Provider value={navigation}>
<OuterWrapper style={tabContainerStyle}>
{ leftIcon }
<TabWrapper>
{state.routes.map((route, i) => {
return (
<Tab
key={route.key}
onPress={() => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!event.defaultPrevented) {
navigation.dispatch({
...TabActions.jumpTo(route.name),
target: state.key,
});
}
}}
style={descriptors[route.key].options.tabStyle}
>
{ descriptors[route.key].options.label ?? <Label active={state.index === i}>{descriptors[route.key].options.title || route.name}</Label> }
</Tab>
)
})}
</TabWrapper>
{ rightIcon }
</OuterWrapper>
<View style={[{ flex: 1 }, contentStyle]}>
{descriptors[state.routes[state.index].key].render()}
</View>
</NavigationHelpersContext.Provider>
);
}
const OuterWrapper = styled.View`
height: 55px;
flex-direction: row;
justify-content: space-between;
background-color: ${Colors.grey1};
`
const TabWrapper = styled.View`
flex: 1;
flex-direction: row;
justify-content: space-evenly;
`
const Tab = styled.TouchableOpacity`
padding: 0 24px;
justify-content: center;
height: 100%;
`
const Label = styled.Text`
font-family: Futura-Medium;
font-size: 26px;
color: ${({ active }) => active ? Colors.grey6 : Colors.grey3};
`
export default createNavigatorFactory(customTabNavigator)
import customTabNavigator from './customTabNavigator'
import * as React from 'react';
import { View, Image } from 'react-native'
import {
ProjectsScreen,
RenderScreen,
EventsScreen,
CameraScreen
} from '../screens';
import Colors from '../constants/Colors'
import logo from '../assets/images/icon.png'
import { Ionicons } from '#expo/vector-icons';
import { TouchableOpacity } from 'react-native-gesture-handler';
const TopTab = customTabNavigator();
const INITIAL_ROUTE_NAME = 'Home';
export default function MainNavigator({ navigation, route }) {
navigation.setOptions({ headerTitle: getHeaderTitle(route) });
return (
<TopTab.Navigator
initialRouteName={INITIAL_ROUTE_NAME}
leftIcon={(
<TouchableOpacity style={{ height: "100%", justifyContent: "center" }} onPress={() => alert("Whatever")}>
<Image source={logo} style={{ resizeMode: "center", width: 70, height: 40 }} />
</TouchableOpacity>
)}
>
<TopTab.Screen
name="Home"
component={ProjectsScreen}
options={{
title: 'Proyectos',
}}
/>
<TopTab.Screen
name="Preview"
component={EventsScreen}
options={{
title: 'Eventos',
}}
/>
<TopTab.Screen
name="Render"
component={RenderScreen}
options={{
title: 'Mi cuenta',
}}
/>
<TopTab.Screen
name="Camera"
component={CameraScreen}
options={{
title: "Camera",
label: (
<View style={{ width: 36, height: 32, backgroundColor: Colors.grey3, borderRadius: 3, alignItems: "center", justifyContent: "center" }}>
<Ionicons name="md-camera" style={{ color: Colors.grey5 }} size={25} />
</View>
),
tabStyle: { flexDirection: "row", alignItems: "center", justifyContent: "flex-end", flex: 1 }
}}
/>
</TopTab.Navigator>
);
}
function getHeaderTitle(route) {
const routeName = route.state?.routes[route.state.index]?.name ?? INITIAL_ROUTE_NAME;
switch (routeName) {
case 'Home':
return 'Montar vídeo';
case 'Preview':
return 'Previsualizar vídeo';
case 'Render':
return 'Renderizar';
case 'Gallery':
return 'Galería'
case 'Camera':
return 'Camera'
}
}
To the example of https://reactnavigation.org/docs/custom-navigators I added a different styling and two new props, leftIcon and rightIcon. This props receive a component for render it to the corresponding side of the tab wrapper. And this components can be TouchableWhatevers with a custom onPress not related with a screen :P
I hope it helps, I almost throw myself through the window until I made it work, haha
step-1:- In bottomTabNav.js to component-prop give a screen which returns nothing
import React from 'react'
const AddMoreScreen = () => {
return null
}
export default AddMoreScreen
//I created AddMoreScreen.js component
step-2:- As mentioned in step-1, I am giving a screen that renders nothing to component prop, later in options prop I will tap tabBarButton object & returns a custom button to it
...
<Tab.Screen
name={"Add"}
component={AddMoreScreen}
options={{
tabBarButton: ()=> <AddMoreModal />
}}
/>
...
step-3:- and finally our center button code, in my case, if I press button a modal has to appear from the bottom, just change the below codes for your requirements. AddMoreModal.js
export default function AddMoreModal() {
const [modalVisible, setModalVisible] = useState(false);
return (
<View style={{ marginTop: 15, marginLeft: 10, marginRight: 10, }}>
<TouchableOpacity
onPress={() => {
setModalVisible(true);
}}
>
<View style={styles.buttonStyle}>
<Image
source={icons.quickAddOutlined}
style={styles.bottomTabImage}
/>
<Text style={styles.bottomTabText}>Add</Text>
</View>
</TouchableOpacity>
<View style={styles.container}>
<Modal
backdropOpacity={0.3}
isVisible={modalVisible}
onBackdropPress={() => setModalVisible(false)}
style={styles.contentView}
>
<View style={styles.content}>
<Text style={styles.contentTitle}>Hi 👋!</Text>
<Text>Welcome to CRAZY MIDDLE BUTTON! forgotten by react-native navigation</Text>
</View>
</Modal>
</View>
</View>
);
}
const styles = StyleSheet.create({
content: {
backgroundColor: "white",
padding: 22,
justifyContent: "center",
alignItems: "center",
borderTopRightRadius: 17,
borderTopLeftRadius: 17,
},
contentTitle: {
fontSize: 20,
marginBottom: 12,
},
contentView: {
justifyContent: "flex-end",
margin: 0,
},
buttonStyle: {
marginBottom: 0,
alignItems:'center',
justifyContent:'center'
},
bottomTabImage: {
width: 25,
height: 25,
},
bottomTabText: {
marginTop: 4,
fontSize: FONTS.body3.fontSize,
fontFamily: FONTS.body3.fontFamily,
color: COLORS.fontGray90,
},
});
step-4:-