Custom Tab Bar React Navigation 5
Asked Answered
F

4

23

I'm trying to make a tab bar like in the picture bellow, using React Navigation.

I tried some codes, but nothing worked. Some codes are from previous React Navigation Version. The really problem is make the tab bar have a margin from from bottom and both sides, and borders rounded.

Anyone can help me please?!

enter image description here

Floris answered 28/5, 2020 at 18:19 Comment(0)
M
45

here is demo: https://snack.expo.io/@nomi9995/createbottomtabnavigator-%7C-react-navigation

you can use tabBar props to make custom TABBAR

<NavigationContainer>
      <Tab.Navigator tabBar={props => <MyTabBar {...props} />}>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
    </NavigationContainer>

MyTabBar Component

function MyTabBar({ state, descriptors, navigation }) {
  return (
    <View style={{ flexDirection: 'row',backgroundColor:"#F4AF5F",height:50,borderRadius:50,justifyContent:"center",alignItems:"center" }}>
      {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,
          });

          if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }
        };

        const onLongPress = () => {
          navigation.emit({
            type: 'tabLongPress',
            target: route.key,
          });
        };

        return (
          <TouchableOpacity
            accessibilityRole="button"
            accessibilityStates={isFocused ? ['selected'] : []}
            accessibilityLabel={options.tabBarAccessibilityLabel}
            testID={options.tabBarTestID}
            onPress={onPress}
            onLongPress={onLongPress}
            style={{ flex: 1, alignItems:"center" }}
          >
            <Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
              {label}
            </Text>
          </TouchableOpacity>
        );
      })}
    </View>
  );
}
Milkweed answered 28/5, 2020 at 19:28 Comment(10)
Yeah, with that I can customize the content inside tab bar. But I can't make rounded border for tab bar and I can't make a margin between tab bar and left/right/bottom screen.Floris
in demo project you can see the rounded border and you can make margin between tab by changing style ob TouchableOpacity in exampleMilkweed
In demo code I can see a white background that show the limit from screen page and tab barFloris
you can give style properties to adjust your tabbatMilkweed
I tried override this white background but no successFloris
now you can check snack.expo.io/@nomi9995/…Milkweed
I forgot, sorry xDFloris
How to add icons?Stillage
Any update on How we can add icons for tabs??Manualmanubrium
@SharadSKatre May be its too late but you can add icons by replacing text with Image, or can add view with both text and image. <Image source={require("image path")} style={styles.image} />Fleeting
I
5

The key to this is to add the style position: 'absolute' to the outer <View> container on your custom TabBar. This will get rid of the white background issue.

Isotron answered 5/8, 2020 at 18:55 Comment(1)
No this makes the entire navbar disappearAllodial
S
0

If it doesn't appear, add it to your custom tabBar root <View> { position: 'absolute', bottom: 0, right: 0, width: '100%', height: 50 }

Shebashebang answered 26/3, 2023 at 10:3 Comment(0)
C
0

This can be achieved without a custom bar using screenOptions function and then standard styles. Like using tabBarStyle and setting position to absolute and setting margins. This provides full control of styling the bar and based on the route too when needed.

<Tab.Navigator
  screenOptions={({ route }) => ({
    tabBarActiveTintColor: 'black',
    tabBarInactiveTintColor: 'white',
    tabBarActiveBackgroundColor: 'yellow',
    tabBarInactiveBackgroundColor: 'black',
    tabBarStyle: {
      position: 'absolute',
      height: 60,
      margin: 10,
      borderRadius: 30,
      borderTopWidth: 0,
      backgroundColor: 'black',
    },
    tabBarItemStyle: {
      margin: 10,
      borderRadius: 30,
    },
    tabBarIconStyle: { display: 'none' },
    tabBarLabel: ({ focused, color }) => {
      let icon = '';
      switch (route.name) {
        case 'Home':
          icon = 'home';
          break;
        case 'Profile':
          icon = 'account';
          break;
        case 'Settings':
          icon = 'tools';
          break;
      }
      return (
        <View
          style={{
            flex: 1,
            flexDirection: 'row',
            justifyContent: 'center',
            alignItems: 'center',
          }}>
          <MaterialCommunityIcons name={icon} color={color} size={24} />
          {focused && <Text>{route.name}</Text>}
        </View>
      );
    },
  })}>
  <Tab.Screen name="Home" component={Home} />
  <Tab.Screen name="Profile" component={Profile} />
  <Tab.Screen name="Settings" component={Settings} />
</Tab.Navigator>
Cimmerian answered 18/1 at 18:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.