如何使用 createBottomTabNavigator 将 TouchableWithoutFeedback 和 TouchableNativeFeedback 呈现为选项卡按钮?

How to render TouchableWithoutFeedback and TouchableNativeFeedback as tab buttons with createBottomTabNavigator?

我正在尝试使用 createBottomTabNavigator(来自 @react-navigation/bottom-tabs v5)。我唯一无法更改的是选项卡按钮。默认值很好,但我想在 Android 上使用 TouchableNativeFeedback 并在 iOS 上使用 TouchableWithoutFeedback(默认值)。

所以我创建了 this snack,唯一正确呈现的 Touchable 是 TouchableOpacity,其他的在视觉上是损坏的并且在按下时没有效果(导航不工作)。

正确呈现 TouchableNativeFeedbackTouchableWithoutFeedback 缺少什么?

import React from 'react';
import {
  Text,
  TouchableOpacity,
  TouchableWithoutFeedback,
  TouchableNativeFeedback,
  StyleSheet,
} from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { MaterialCommunityIcons } from '@expo/vector-icons';

const ScreenWithoutFeedback = () => <Text>Without Feedback</Text>;
const ScreenOpacity = () => <Text>Opacity</Text>;
const ScreenNativeFeedback = () => <Text>Native Feedback</Text>;

const buttonWithoutFeedback = (props) => (
  <TouchableWithoutFeedback {...props} />
);

const buttonOpacity = (props) => <TouchableOpacity {...props} />;

// I didn't set the Ripple yet because it isn't rendering correctly
const buttonNativeFeedback = (props) => <TouchableNativeFeedback {...props} />;

const TabNavigator = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <TabNavigator.Navigator
        initialRouteName="Collect"
        tabBarOptions={{
          activeTintColor: '#2962ff',
          inactiveTintColor: '#666',
          labelStyle: {
            fontSize: 12,
          },
          tabStyle: {
            maxWidth: 168,
            minWidth: 80,
            paddingHorizontal: 12,
            paddingTop: 8,
            paddingBottom: 12,
          },
          style: {
            alignItems: 'center',
            height: 56,
          },
        }}>
        <TabNavigator.Screen
          name="Without"
          component={ScreenWithoutFeedback}
          options={{
            tabBarIcon: ({ color }) => (
              <MaterialCommunityIcons name="account" color={color} size={24} />
            ),
            tabBarLabel: 'WithoutFeedback',
            tabBarButton: buttonWithoutFeedback,
          }}
        />
        <TabNavigator.Screen
          name="Opacity"
          component={ScreenOpacity}
          options={{
            tabBarIcon: ({ color }) => (
              <MaterialCommunityIcons name="settings" color={color} size={24} />
            ),
            tabBarLabel: 'Opacity',
            tabBarButton: buttonOpacity,
          }}
        />
        <TabNavigator.Screen
          name="Native"
          component={ScreenNativeFeedback}
          options={{
            tabBarIcon: ({ color }) => (
              <MaterialCommunityIcons name="logout" color={color} size={24} />
            ),
            tabBarLabel: 'NativeFeedback',
            tabBarButton: buttonNativeFeedback,
          }}
        />
      </TabNavigator.Navigator>
    </NavigationContainer>
  );
}

当前结果:


我知道有一个 createMaterialBottomTabNavigator(来自 @react-navigation/material-bottom-tabs),但使用它我需要配置更多我无法在测试中使用的东西。

要修复它,请在 Touchable 中渲染 <View> 并在该视图中渲染 children。此外, style 道具应该传递给 <View>.

TouchableNativeFeedback

const buttonNativeFeedback = ({ children, style, ...props }) => (
  <TouchableNativeFeedback
    {...props}
    useForeground={true}
    background={TouchableNativeFeedback.Ripple('#2962ff1f', true)}>
    <View style={style}>{children}</View>
  </TouchableNativeFeedback>
);

TouchableWithoutFeedback

const buttonWithoutFeedback = ({ children, style, ...props }) => (
  <TouchableWithoutFeedback {...props}>
    <View style={style}>{children}</View>
  </TouchableWithoutFeedback>
);

Snack with the working code.