Reputation: 51
I'm using Material Top Tabs Navigator from React Navigation. Here's an example:
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
const Tab = createMaterialTopTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Chat" component={ChatScreen} />
<Tab.Screen name="Contacts" component={ContactsScreen} />
<Tab.Screen name="Albums" component={AlbumsScreen} />
</Tab.Navigator>
);
}
By default, tab indicator is displayed only for the active tab like the following:
However I want inactive tabs to have tab indicators as well. These inactive tabs indicators should be a different color like below:
I can change default indicator color for active tab by adding tabBarIndicatorStyle
option to navigator:
<Tab.Navigator
screenOptions={{ tabBarIndicatorStyle: { backgroundColor: colors.white } }}
>
<Tab.Screen name="Chat" component={ChatScreen} />
<Tab.Screen name="Contacts" component={ContactsScreen} />
<Tab.Screen name="Albums" component={AlbumsScreen} />
</Tab.Navigator>
But how to set indicator color for inactive tabs?
Upvotes: 0
Views: 230
Reputation: 1285
In @react-navigation/material-top-tabs, there isn't a direct prop for setting the inactive indicator color.
To achieve different styles for active and inactive tab indicators, you would need a custom tab bar component. Here's how you can create a custom tab bar to handle different indicator colors for active and inactive tabs:
yarn add react-native-tab-view
Create a custom tab bar component:
import * as React from 'react';
import { View, useWindowDimensions } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import { TabBar, TabView } from 'react-native-tab-view';
const Tab = createMaterialTopTabNavigator();
function HomeScreen() {
return <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Home</Text></View>;
}
function SettingsScreen() {
return <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Settings</Text></View>;
}
function CustomTabBar(props) {
const { state, navigation, position } = props;
const { width } = useWindowDimensions();
return (
<TabBar
{...props}
indicatorStyle={{ backgroundColor: 'blue' }} // Active indicator color
renderIndicator={({ route }) => {
const isFocused = state.index === state.routes.indexOf(route);
return (
<View
style={{
backgroundColor: isFocused ? 'blue' : 'gray', // Active and inactive indicator colors
height: 4,
width: width / state.routes.length,
}}
/>
);
}}
/>
);
}
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBar={(props) => <CustomTabBar {...props} />}
screenOptions={{
tabBarActiveTintColor: 'blue', // Color of the active tab text
tabBarInactiveTintColor: 'gray', // Color of the inactive tab text
}}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
Upvotes: 0
Reputation: 323
To set the style of the indicator under the inactive tab, you need to use a custom tab bar component because the default createMaterialTopTabNavigator does not support directly styling the indicator for inactive tabs. You can achieve this by customizing the tab bar's rendering.
Here's an example of how you can create a custom tab bar component to style the indicator under the inactive tabs:
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
function CustomTabBar({ state, descriptors, navigation, position }) {
return (
<View style={{ flexDirection: 'row', backgroundColor: 'white' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
return (
<TouchableOpacity
key={route.key}
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1, alignItems: 'center', padding: 10 }}
>
<Text style={{ color: isFocused ? 'blue' : 'gray' }}>
{label}
</Text>
<View
style={{
height: 2,
backgroundColor: isFocused ? 'blue' : 'gray',
marginTop: 4,
width: '100%',
}}
/>
</TouchableOpacity>
);
})}
</View>
);
}
export default CustomTabBar;
you can use custom tab bar like this:
import React from 'react';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import ChatScreen from './ChatScreen';
import ContactsScreen from './ContactsScreen';
import AlbumsScreen from './AlbumsScreen';
import CustomTabBar from './CustomTabBar'; // Import the custom tab bar
const Tab = createMaterialTopTabNavigator();
function MyTabs() {
return (
<Tab.Navigator tabBar={props => <CustomTabBar {...props} />}>
<Tab.Screen name="Chat" component={ChatScreen} />
<Tab.Screen name="Contacts" component={ContactsScreen} />
<Tab.Screen name="Albums" component={AlbumsScreen} />
</Tab.Navigator>
);
}
export default MyTabs;
Upvotes: 0