React-Native bottomTabNavigation con un botón grande en el medio

Aug 22 2020

Quiero crear un bottomTabNavigation como este:

Logré crear un tabNavigation como este colocando una imagen, position:'absolute'pero la imagen está desbordando la pestaña y no se puede hacer clic en la parte que se desborda.

Mi código en este momento:

    <Tab.Navigator initialRouteName="Activity" tabBarOptions={{
        showIcon: true,
        showLabel: false,
        activeTintColor: 'blue',
      }}>

      <Tab.Screen name="Theme" component={Themes} options={{
        tabBarIcon: () => (<Image source={require('../Images/list_blue.png')} style={styles.icon}/>)
      }}/>

      <Tab.Screen name="Activity" component={Activity} options={{
        tabBarIcon: () => (<Image source={require('../Images/idea_blue.png')} style={styles.main_icon}/>)
      }}/>

      <Tab.Screen name="Add" component={Add} options={{
        tabBarIcon: () => (<Image source={require('../Images/plus_blue.png') style={styles.icon}/>)
      }}/>

  </Tab.Navigator>

    //Styles
    icon: {
      width: 40,
      height: 40,
    },
    main_icon: {
      position: 'absolute',
      bottom: -30,
      width: 115,
      height: 115,
    }

Luego creé un tabNavigation personalizado con el prop tabBar={props => <CustomTabBar {...props} />}pero todavía tengo el mismo problema:

el cuadrado rojo es una opacidad táctil, pero solo se puede hacer clic en la parte verde, la parte sobre la pestaña todavía no se puede hacer clic y no entiendo por qué ...

¿Tiene una idea de cómo hacer un botón tan grande en el medio de la navegación de la pestaña inferior?

Respuestas

BasvanderLinden Aug 25 2020 at 12:28

Creo que lo conseguí al crear una barra de pestañas personalizada y pasar ese componente al tabBaraccesorio del navegador de pestañas:

function CustomTabBar({ state, descriptors, navigation, position }) {
  return (
    <View
      style={{
        flexDirection: 'row',
        height: 50,
        alignItems: 'center',
        justifyContent: 'space-around',
      }}>
      {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,
          });
        };

        const inputRange = state.routes.map((_, i) => i);

        return (
          <TouchableOpacity
            accessibilityRole="button"
            accessibilityStates={isFocused ? ['selected'] : []}
            accessibilityLabel={options.tabBarAccessibilityLabel}
            testID={options.tabBarTestID}
            onPress={onPress}
            onLongPress={onLongPress}>
            {route.name === 'Screen 2' ? (
              <Image
                style={styles.logo}
                source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
              />
            ) : (
              <Image
                style={styles.logo_tiny}
                source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
              />
            )}
          </TouchableOpacity>
        );
      })}
    </View>
  );
}

const styles = StyleSheet.create({
  logo: {
    width: 80,
    height: 80,
    bottom: 0,
  },
  logo_tiny: {
    width: 30,
    height: 30,
  },
});

Luego, puede pasar CustomTabBar al navegador de pestañas de esta manera:

const App = () => {
  return (
    <NavigationContainer>
      <Tab.Navigator
        initialRouteName="Activity"
        tabBarOptions={{
          showIcon: true,
          showLabel: false,
          activeTintColor: 'blue',
        }}
        tabBar={(props) => <CustomTabBar {...props} />}>
        <Tab.Screen name="Screen 1" component={Screen1} />
        <Tab.Screen name="Screen 2" component={Screen2} />
        <Tab.Screen name="Screen 3" component={Screen3} />
      </Tab.Navigator>
    </NavigationContainer>
  );
};