I am using React Navigations tabBar with my React Native project, and I don't know how to change the background color of my bottom tab bar properly. I used Expo to make my app and I have also edited app.json to have the correct backgroundColor, yet nothing changes. Here is my code:
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
screenOptions={{
tabBarActiveTintColor: "#E40066",
tabBarInactiveTintColor: "#fff",
tabBarActiveBackgroundColor: "#171717",
tabBarInactiveBackgroundColor: "#171717",
headerShown: false,
tabBarStyle: {
borderWidth: 1,
},
style: {
backgroundColor: "#171717",
},
}}
>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="glass-cocktail"
color={color}
size={size}
/>
),
}}
/>
<Tab.Screen
name="Search"
component={Search}
options={{
tabBarLabel: "Search",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="magnify" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Saved"
component={Saved}
options={{
tabBarLabel: "Saved",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="heart" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
}
export default function App() {
const navTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: "#171717",
},
};
return (
<NavigationContainer theme={navTheme}>
<MyTabs style={{ backgroundColor: "#171717" }}></MyTabs>
</NavigationContainer>
);
}
Yet my tabBar looks like this, I want it to be #171717, not white... Thank you in advance
The solution was to make a theme to change the background color:
export default function App() {
const navTheme = {
colors: {
background: "#171717"
}
};
return (
<NavigationContainer theme={navTheme}>
<MyTabs style={{ backgroundColor: "#171717" }}></MyTabs>
</NavigationContainer>
);
}
You can use this
<Tab.Navigator
tabBarOptions={{
style: {
backgroundColor:'#171717 '
}
}}>
{Screens}
</Tab.Navigator>
Related
I just start learning React Native, and I added my bottom nav using Material Bottom Tabs.
My only issue is this purple circle around my icon when selected. I checked the docs looking for this default setting but couldn't find it.
Here is my code:
const Tab = createMaterialBottomTabNavigator();
const App = () => {
const [loaded] = useFonts({
InterBold: require("./assets/fonts/Inter-Bold.ttf"),
InterSemiBold: require("./assets/fonts/Inter-SemiBold.ttf"),
InterMedium: require("./assets/fonts/Inter-Medium.ttf"),
InterRegular: require("./assets/fonts/Inter-Regular.ttf"),
InterLight: require("./assets/fonts/Inter-Light.ttf"),
});
if (!loaded) return null;
return (
<NavigationContainer theme={theme}>
<Tab.Navigator initialRouteName="Menu principal"
activeColor="#f0edf6"
inactiveColor="white"
barStyle={{ backgroundColor: 'black' }}
>
<Tab.Screen name="Menu principal" component={Home}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Collections" component={Collections}
options={{
tabBarLabel: 'Collections',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="cards" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Associations" component={Associations}
options={{
tabBarLabel: 'Associations',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="account-group" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Classement" component={Classement}
options={{
tabBarLabel: 'Classement',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="trophy" color={color} size={26} />
),
}}
/>
<Tab.Screen name="News" component={News}
options={{
tabBarLabel: 'News',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="newspaper" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
Here is the solution I found. You have to npm install react-native-paper, import, and use it.
To use react-native-paper to change the little circle tab buttons, wrap <Tab.Navigator>...</Tab.Navigator> with <PaperProvider theme={theme}> as shown below.
Finally, create a const theme like I did, and change the secondaryContainer to whatever color you want.
P.S. make sure to change your import names as shown to not conflict with the Provider for redux.
import {
MD3LightTheme as DefaultTheme,
Provider as PaperProvider,
} from "react-native-paper";
const Tab = createMaterialBottomTabNavigator();
const theme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
secondaryContainer: "red",
},
};
const App = () => {
return (
<NavigationContainer>
<PaperProvider theme={theme}>
<Tab.Navigator initialRouteName="Menu principal"
activeColor="#f0edf6"
inactiveColor="white"
barStyle={{ backgroundColor: 'black' }}
>
// rest of your code
</Tab.Navigator>
</PaperProvider>
</NavigationContainer>
)
}
Hy, I'm using react-native bottom tabs navigation the first time I'm having an issue to re-render the screen when I get back to some other tab. I try to use isFocused in useEffect() but it didn't work for me.
const LandScreen = ({navigation}) => {
return (
<Tab.Navigator
tabBarOptions={{
showLabel: false,
activeTintColor: colors.primary,
inactiveTintColor: colors.textHead,
}}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'home' : 'home';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
<Tab.Screen
name="Message"
component={ChatStackScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'chatbox-ellipses' : 'chatbox-ellipses';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
<Tab.Screen
name="Requests"
component={RequestStackScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'heart' : 'heart';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
<Tab.Screen
name="Notifications"
component={NotificationStackScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'notifications' : 'notifications';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
<Tab.Screen
name="Profile"
component={ProfileScreenScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'person' : 'person';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
</Tab.Navigator>
);
};
Each Tab component having a stack inside of it.
Someone informs me how to rerender the bottom navigation tabs?
If I understand you correctly, you want the screen to re-render when you click on a bottom tab navigation button.
This can be accomplished by either adding the 'focus' event listener via the react navigation docs https://reactnavigation.org/docs/function-after-focusing-screen/
Or by explicitly calling 'navigation.navigate' when a bottom tab is pressed.
Assuming I understand your question, all you want to do is re-render the icons when the tab changes?
React Navigation has docs & an example for this use-case for tab-based navigation here.
Posting the code sample from the docs here for ease-of-access:
import Ionicons from 'react-native-vector-icons/Ionicons';
// (...)
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: 'tomato',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
If your question meant re-rendering the screen when the tab changes:
Leveraging useEffect with useIsFocused should work when changing tabs. You haven't included your example with those hooks, so I'm not exactly sure how you're using it.
The following snippet should get you up and running with said hooks. In this case, you can run whatever you want inside the useEffect when switching tabs, where the active tab gets triggered.
If for some reason you just want the UI to get updated/persisted based on some data between tab changes you might want to consider using Redux.
import React, { useEffect } from "react";
import { Text, View } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import { useIsFocused } from "#react-navigation/core";
function HomeScreen() {
const isFocused = useIsFocused();
useEffect(() => {
if (isFocused) {
console.log("HELLO HOME");
}
}, [isFocused]);
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Home!</Text>
</View>
);
}
function SettingsScreen() {
const isFocused = useIsFocused();
useEffect(() => {
if (isFocused) {
console.log("HELLO SETTINGS");
}
}, [isFocused]);
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
Using React Navigation (6), I've got bottom tabs set up as my main navigator:
export function TabNavigator() {
const getColor = ({ focused, color }) => (focused ? palette.blue : color)
return (
<Tab.Navigator screenOptions={{ headerShown: false }}>
<Tab.Screen
name="home"
component={HomeScreen}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="home-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="favourites"
component={FavouritesScreen}
options={{
tabBarLabel: "Favourites",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="heart-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="about"
component={AboutYouScreen}
options={{
tabBarLabel: "About you",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="person-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="bottomchat"
component={ChatNavigator}
options={{
tabBarLabel: "Check-in",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="chatbubble-ellipses-outline" color={getColor(rest)} size={size} />
),
}}
/>
</Tab.Navigator>
)
}
With the last tab (the ChatNavigator), I want the screen it opens to be a full screen modal, hiding the bottom tab bar (the user can exit out if it via a back button at the top).
Is this possible?
As I was writing this question I found an answer which actually worked for me on this blog post
The solution:
Create the full screen modal in your parent stack
Pass in a mock component to the tab screen (this will never get called)
Add a listener to the tab component that prevents default and then navigates to the page of your choice
So for me:
const ChatBase = () => <View style={{ flex: 1, backgroundColor: "red" }} />
export function TabNavigator() {
const getColor = ({ focused, color }) => (focused ? palette.blue : color)
return (
<Tab.Navigator screenOptions={{ headerShown: false }}>
<Tab.Screen
name="home"
component={HomeScreen}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="home-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="favourites"
component={FavouritesScreen}
options={{
tabBarLabel: "Favourites",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="heart-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="about"
component={AboutYouScreen}
options={{
tabBarLabel: "About you",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="person-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="bottomchat"
/* Pass in a blank component as the base (this never gets shown) */
component={ChatBase}
options={{
tabBarLabel: "Check-in",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="chatbubble-ellipses-outline" color={getColor(rest)} size={size} />
),
}}
listeners={({ navigation }) => ({
tabPress: (e) => {
e.preventDefault()
navigation.navigate("chat")
},
})}
/>
</Tab.Navigator>
)
}
In my root stack navigator, I've got a screen called chat that gets called:
export function MainNavigator() {
return (
<Stack.Navigator
screenOptions={{
cardStyle: { backgroundColor: "transparent" },
headerShown: false,
}}
>
<Stack.Screen name="main" component={TabNavigator} />
<Stack.Screen name="chat" component={ChatScreen} />
</Stack.Navigator>
)
}
Use listener/tabPress props with navigator, but navigator from TabNavigator component
export function TabNavigator( { navigation } ) { // <-- use this navitagor
.........
.........
<Tab.Screen
name="bottomchat"
component={ AnyComponent } // <-- ignored
options={{
tabBarLabel: "Check-in",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="chatbubble-ellipses-outline" color={getColor(rest)} size={size} />
),
}}
listeners={() => ({
tabPress: (e) => {
e.preventDefault()
navigation.navigate("ChatComponent") // <-- Here you put the name where the chat component is declared
},
})}
/>
</Tab.Navigator>
)
}
I'm using React Navigation drawer and i want to have a different fontSize (custom styling) for each drawer screen title. Changing the labelStyle in the drawerContentOptions would change the fontSize for all the drawer screen titles and I wanna have each one customized.
<Drawer.Navigator
drawerStyle={{
backgroundColor: Colors.mainBackground,
width: WIDTH * 0.6,
}}
drawerContentOptions={{
activeTintColor: Colors.mainForeGround,
itemStyle: { marginVertical: 8, marginHorizontal: 8 },
labelStyle: {
fontSize: 18,
},
}}
>
<Drawer.Screen name="Profile" component={Profile}
options={{
title: 'Profile Name',
drawerIcon: ({ color }) => {
return <Icon name={'account'} size={ICON_SIZE} color={color} />
},
}}
/>
<Drawer.Screen name="Menu" component={Menu}
options={{
title: 'Shopping menu',
drawerIcon: ({ color }) => {
return <Icon name={'menu'} size={ICON_SIZE} color={color} />
},
}}
/>
<Drawer.Screen name="Cart" component={Cart}
options={{
title: 'Shopping cart',
drawerIcon: ({ color }) => {
return <Icon name={'cart'} size={ICON_SIZE} color={color} />
},
}}
/>
<Drawer.Screen name="Settings" component={Settings}
options={{
title: 'Settings',
drawerIcon: ({ color }) => {
return <Icon2 name={'settings'} size={ICON_SIZE} color={color} />
},
}}
/>
</Drawer.Navigator>
Drawer.Navigator provides a prop called drawContent which needs to return a React component which will be used to render the contents of the drawer.
Usage:
function CustomDrawerContent(props) {
return (
<Here goes your code for rendering individual elements of your drawer>
);
}
const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
<Drawer.Navigator drawerContent={props => <CustomDrawerContent {...props} />}>
<Drawer.Screen name="Feed" component={Feed} />
<Drawer.Screen name="Article" component={Article} />
</Drawer.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}
For full example, refer link
How to apply a style on the bottom tab so that it looks similar to this model?
Image
<HomeTabs.Navigator
screenOptions={({route})=>({
tabBarIcon: ({color, size})=>{
const {name} = icons[route.name]
return <Ionicons name={name} size={size} color={color}/>
}
})}
tabBarOptions={
{
style: {
height: 50,
width: 300,
flexDirection: 'column',
alignSelf: 'center',
elevation: 2,
borderTopStartRadius: 5,
borderTopEndRadius: 5,
},
activeTintColor: '#845EC2',
}
}
>
result:
Result
There is no such container
tabBarStyle worked for me.
Refer official documentation for more styling options click here.
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused? 'ios-home-sharp': 'ios-home-outline';
} else if (route.name === 'Favourites') {
iconName = focused ? 'ios-heart-sharp' : 'ios-heart-outline';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#58ceb2',
tabBarInactiveTintColor: 'gray',
//Tab bar styles can be added here
tabBarStyle:{paddingVertical: 5,borderTopLeftRadius:15,borderTopRightRadius:15,backgroundColor:'white',position:'absolute',height:50},
tabBarLabelStyle:{paddingBottom:3},
})}
>
<Tab.Screen name="Home" component={HomeStackScreen} options={{headerShown: false}}/>
<Tab.Screen name="Favourites" component={FavouritesScreen} />
</Tab.Navigator>
This is what I came up with since there is no code. Hope this can help.
const Tab = createMaterialBottomTabNavigator();
const Navigator = () => {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName="Something"
barStyle={{ marginLeft:10, marginRight:10 }} //This is where you can manipulate its look.
>
<Tab.Screen name="firstOne" component={Something1}/>
<Tab.Screen name="secondOne" component={Something2}/>
<Tab.Screen name="thirdOne" component={Something3}/>
</Tab.Navigator>
</NavigationContainer>
);
}
Note the barStyle prop. That's where you can change how the bottom bar displays.
try this
add tabbaroptions
example
<tab.navigation tabbaroptions={{barstyle : styles.container}} >
I tried this and it works!
const Navigator = () => (
<Tab.Navigator tabBarOptions={{style:{backgroundColor: 'yellow'}}}> //do styling here
<Tab.Screen/>
<Tab.Screen/>
<Tab.Screen/>
</Tab.Navigator>
)
export default Navigator;
I got it to work with:
const screenOptionStyle = {
headerStyle: {
backgroundColor: Colors.darkGrey,
},
headerTintColor: Colors.richGold,
headerBackTitle: "",
tabBarStyle: [{ backgroundColor: Colors.darkGrey }], <--- HERE
};
<Tab.Navigator screenOptions={screenOptionStyle}>