React-中央に大きなボタンがあるネイティブbottomTabNavigation

Aug 22 2020

次のようなbottomTabNavigationを作成したいと思います。

画像を入れてこのようなtabNavigationを作成できましたposition:'absolute'が、画像がタブにあふれ、あふれた部分をクリックできません。

現時点での私のコード:

    <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,
    }

次に、小道具を使用してcust tabNavigationを作成しましたtabBar={props => <CustomTabBar {...props} />}が、それでも同じ問題が発生します。

赤い四角はtouchableOpacityですが、クリック可能なのは緑の部分だけで、タブの上の部分はまだクリックできず、理由がわかりません...

bottomTabNavigationの中央にこのような大きなボタンを作成する方法を知っていますか?

回答

BasvanderLinden Aug 25 2020 at 12:28

カスタムタブバーを作成し、そのコンポーネントをtabBarタブナビゲーターの支柱に渡すことで、機能するようになったと思います。

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,
  },
});

次に、次のようにCustomTabBarをタブナビゲーターに渡すことができます。

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>
  );
};