leabum
leabum

Reputation: 395

Make custom button appear on top of React Native Navigation Bar

I want to create a navigation bar with a large custom button in the middle. The routing and everything works, but the button gets cut off at the border of the navigation bar component. How can I make it, so that the button displays on top? I tried zIndex, but that did not work for me. Thank you.

const HomeIcon = <Icon name="time-outline" size={40} color="#829a9a" />;
const ScanIcon = <Icon name="qr-code-outline" size={60} color="#829a9a" />;
const GiftsIcon = <Icon name="gift-outline" size={40} color="#829a9a" />;

const App: () => Node = () => {
    const customTabBarStyle = {
        activeTintColor: '#3ED77C',
        inactiveTintColor: '#829a9a',
        allowFontScaling: true,
        labelStyle: { fontSize: 14, paddingTop: 5 },
        tabStyle: { paddingTop: 5 },
        style: { height: 70},
      }
  return (
      <NavigationContainer>
        <Tab.Navigator tabBarOptions={customTabBarStyle}>
            <Tab.Screen name="Home" component={HomeScreen}
                 options={{
                   tabBarLabel: 'Aktuell',
                   tabBarIcon: () => (HomeIcon),
                 }} />
            <Tab.Screen name="Scan" component={ScanScreen}
                options= {({navigation}) => ({
                   tabBarLabel: 'Scanner',
                   tabBarButton: (props) => (
                    <Button onPress={() => navigation.navigate('Scan')}
                        buttonStyle={styles.buttonStyle}
                        icon={ScanIcon}
                      />)
                 })} />
            <Tab.Screen name="Gifts" component={GiftsScreen}
                options={{
                   tabBarLabel: 'Prämien',
                   tabBarIcon: () => (GiftsIcon),
                 }} />
        </Tab.Navigator>
      </NavigationContainer>
  );
};

const styles = StyleSheet.create({
  buttonStyle: {
      bottom: 30,
      justifyContent: 'center',
      alignItems: 'center',
      height: 120,
      width: 120,
      backgroundColor: 'lightgrey',
      borderRadius: 100,
  },
});

export default App;

See image: [1]: https://i.sstatic.net/OB2C1.png

Upvotes: 1

Views: 4016

Answers (3)

Jona Santana
Jona Santana

Reputation: 130

I think its a bit late, but just in case someone still need it, you can just add custom comp. when you define the "Tab.Screen" by simply adding the "headerRight" or "headerLeft" if you need it. Example with you code:

      <Tab.Screen name="Home" component={HomeScreen}
             options={{
               tabBarLabel: 'Aktuell',
               tabBarIcon: () => (HomeIcon),
               // HERE <---
               headerRight: () => (    
                    <Button title="Log In" />
                   ) 
             }} 
             />

Upvotes: 0

Gavin D&#39;mello
Gavin D&#39;mello

Reputation: 433

Use this code to prevent the ScanIcon from being cut off from the top.

navigationOptions: {
    tabBarIcon: ({focused}) => {
        let iconName = require('./{{PATH}}/abc.png');
        return (
            <View
              style={{
                flex: 1,
                width: '102%',
                height: '100%',
                alignItems: 'center',
                backgroundColor: COLOR.AppTheme,
              }}>
              <Image
                style={{
                  position: 'absolute',
                  bottom: 5,
                }}
                source={iconName}
                resizeMode="contain"
              />
            </View>
        );
    },
 },

Clear and simple. Cheers!

Upvotes: 1

Vishal Pawar
Vishal Pawar

Reputation: 1737

I already made similer button check this example->

youtube link- https://youtu.be/vIWi7eLZomk

you can checkout this example https://github.com/vishalpwr/bottom-tab-navigation

const BottomTab = ({ type, color, size = 24, isFocused, index }) => {
  const icon = index == 0 ? 'home' : 'heart';
  const gradient = index == 1;
  return (
    <View>
      {gradient ? (
        <LinearGradient
          colors={[Colors.light, Colors.dark]}
          start={{ x: isFocused ? 0 : 1, y: 0 }} end={{ x: isFocused ? 1 : 0, y: 0 }}
          style={styles.middleIcon}>
          <AppIcon name={'shopping-basket'} type={type} size={size} color={'white'} />
        </LinearGradient>
      ) : (
        <View style={styles.icon}>
          <AppIcon name={icon} type={type} size={size} color={color} />
        </View>
      )}
    </View>
  )
}

const App = () => {
  return (
    <NavigationContainer>
      <TabNavigator />
    </NavigationContainer>
  )
};

const Tab = createBottomTabNavigator();

const TabNavigator = () => {
  return (
    <Tab.Navigator
      tabBar={(props) => <MyTabBar {...props} />}>
      <Tab.Screen name="home" component={HomeScreen} />
      <Tab.Screen name="Shop" component={ShopScreen} />
      <Tab.Screen name="Favorite" component={FavoriteScreen} />
    </Tab.Navigator>
  )
}

const MyTabBar = ({ state, descriptors, navigation }) => {
  return (
    <View
      style={styles.bottomBar}>
      {state.routes.map((route, index) => {
        const isFocused = state.index === index;
        const { options } = descriptors[route.key];

        const onPress = () => {
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
          })
          if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }
        }

        const color = isFocused ? Colors.dark : Colors.gray;

        return (
          <TouchableOpacity
            key={index}
            onPress={onPress}
            testID={options.tabBarTestID}
            accessibilityRole="button"
          >
            <BottomTab
              type={index !== 1 ? Icons.MaterialCommunityIcons : Icons.FontAwesome5}
              index={index}
              isFocused={isFocused}
              size={24}
              color={color}
            />
          </TouchableOpacity>
        )
      })}
    </View>
  )
}

const styles = StyleSheet.create({
  bottomBar: {
    height: 60,
    backgroundColor: 'white',
    alignItems: 'center',
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
  middleIcon: {
    bottom: 18,
    width: 60,
    height: 60,
    borderRadius: 30,
    backgroundColor: 'red',
    justifyContent: 'center',
    alignItems: 'center',
    shadowColor: 'black',
    shadowOffset: { width: 2, height: 2 },
    shadowOpacity: 0.6,
    elevation: 8,
  }
});

Upvotes: 2

Related Questions