如何使用反应本机底部选项卡将顶部边框添加到活动选项卡

How to add top border to tab that is active using react native bottom tabs

我正在使用反应导航 v5。我正在使用底部选项卡导航器。我想在活动选项卡的顶部添加边框。到目前为止,我尝试过的一切都没有奏效。这是我的导航文件(减去导入):

const AuthStack = createStackNavigator()
const InfoStack = createStackNavigator()
const PhotoStack = createStackNavigator()
const ProfitStack = createStackNavigator()
const RehabStack = createStackNavigator()
const DrawerNav = createDrawerNavigator()
const TabNav = createBottomTabNavigator()

const createAuthStack = () => (
   <AuthStack.Navigator>
      <AuthStack.Screen name='Sign Up' component={SignUpScreen} />
      <AuthStack.Screen name='Sign In' component={SignInScreen} />
   </AuthStack.Navigator>
)

const stackOptions = {
   headerStyle: {
      backgroundColor: colors.colorGrayLight,
        borderBottomColor: colors.colorPrimary,
        borderBottomWidth: 2
   },
    
}

const createInfoStack = () => (
   <InfoStack.Navigator screenOptions={stackOptions}>
      <InfoStack.Screen name='Info Stack' component={PropertyInfoScreen} />
   </InfoStack.Navigator>
)

const createProfitStack = () => (
   <ProfitStack.Navigator screenOptions={stackOptions}>
      <PhotoStack.Screen name='Profit Stack' component={ProfitCalculatorScreen} />
   </ProfitStack.Navigator>
)

const createRehabStack = () => (
   <RehabStack.Navigator screenOptions={stackOptions}>
      <RehabStack.Screen name='Rehab Stack' component={RehabCostsScreen} />
   </RehabStack.Navigator>
)

const createPhotosStack = () => (
   <PhotoStack.Navigator screenOptions={stackOptions}>
      <PhotoStack.Screen name='Photo Stack' component={PropertyPhotosScreen} />
   </PhotoStack.Navigator>
)

const createScreenOptions = ({ focused, color, route }) => {
   let imgSrc

   switch (route.name.toLowerCase()) {
      case 'info':
         imgSrc = images.iconPropertyInfo
         break
      case 'profit':
         imgSrc = images.iconProfit
         break
      case 'rehab':
         imgSrc = images.iconRehab
         break
        case 'photos':
            imgSrc = images.iconPhotos 
            break
   }

   return {
      tabBarIcon: ({ focused, color }) => (
         <View style={{ alignItems: 'center', marginTop: 10 }}>
            <Image
               source={imgSrc}
               resizeMode='contain'
               style={{
                  width: 25,
                  height: 25,
                  tintColor: color,
               }}
            />
            <Text style={{ color: color, fontSize: 12 }}>{route.name}</Text>
         </View>
      ),

       tabBarButton: (props) => {
         return (
            <TabBarButton {...props} />
         )
       }
   }
}

const createTabNav = ({ route, navigation}) => {
   const focusedRoute = getFocusedRouteNameFromRoute(route)

   return (
      <TabNav.Navigator
         tabBarOptions={{
            activeTintColor: colors.colorPrimary,
            inactiveTintColor: colors.colorCharcoal,
            keyboardHidesTabBar: true,
            allowFontScaling: false,
            style: {
               backgroundColor: colors.colorGrayLight,
            },
            labelStyle: {
               fontSize: 12,
            },
            showLabel: false,
         }}>
         <TabNav.Screen name='Info' component={createInfoStack} options={createScreenOptions}/>
         <TabNav.Screen name='Profit' component={createProfitStack} options={createScreenOptions} />
         <TabNav.Screen name='Rehab' component={createRehabStack} options={createScreenOptions} />
         <TabNav.Screen name='Photos' component={createPhotosStack} options={createScreenOptions} />
      </TabNav.Navigator>
   )
}

export default MainNav = () => {
   const [isAuthenticated, setIsAuthenticated] = useState(false)

   return (
      <NavigationContainer>
         <DrawerNav.Navigator>
            <DrawerNav.Screen name='Main' component={createTabNav} />
         </DrawerNav.Navigator>
      </NavigationContainer>
   )
}

我试图创建自己的自定义 tabIcon / tabBarButton,但我不知道如何将选项卡是否处于活动状态传递给 tabBarButton。 “focused”或“navigation”道具不会传递到 tabBarButton 函数中。我希望我的底部导航看起来像这里的图片

你可以像这样使用聚焦道具

<Tab.Screen
        name="ScreenName"
        component={Screen}
        options={{
          tabBarIcon: ({ color, focused }) => (
            <View style={styles.individualTabWrapper}>
              {
                focused && <View style={styles.activeDot} />
              }
              <CustomIcon name={'home'} size={focused ? 27 : 25} color={color} />
            </View>
          ),
         
          tabBarLabel: ({ focused, color }) => (
            <>
              <Text style={[styles.label, { color: 'black'}]}>Home</Text>
            </>
          )
        }}
      />

这是我的解决方案,您可以根据需要设置边框。

const Tab = createBottomTabNavigator()

const TAB_ICON = {
    Meals: "fast-food",
    Favorites: "star"
}

const activeTab = (focused,size,color,iconName) => {
    return (
        focused? (
        <View style={{ borderTopWidth:2, width: "100%", height: "100%", borderColor: Colors.ui.primary }}>
            <Ionicons style={{ alignSelf: "center", justifyContent: "center", alignItems: "center" }} name={iconName} size={size} color={color} />
        </View>) :
        (
            <Ionicons name={iconName} size={size} color={color} />
        )
    )
}

const iconOptions = ({ route }) => {
    const iconName = TAB_ICON[route.name];
    return {
        tabBarIcon: ({ focused, size, color }) => (
            size = focused ? 24 : 20,
            activeTab(focused,size,color,iconName)
        ),
        tabBarActiveTintColor: Colors.ui.primary,
        tabBarInactiveTintColor: Colors.ui.secondary,
        tabBarStyle: { backgroundColor: Colors.bg.secondary },
    }
}

export const TabNavigator = () => {
    return (
        <NavigationContainer>
            <Tab.Navigator
                screenOptions={iconOptions}
            >
                <Tab.Screen name="Meals" component={MealsNavigator} options={{ headerShown: false, title: "MEALS" }}></Tab.Screen>
                <Tab.Screen name="Favorites" component={FavoritesScreen} options={{ headerTitleAlign: "center", title: "FAVORITES", tabBarIconStyle: ({ focused }) => (borderTopWidth = 2, borderColor = "black") }}></Tab.Screen>
            </Tab.Navigator>
        </NavigationContainer>
    )
}