如何使用react原生底部选项卡将顶部边框添加到处于活动状态的选项卡

我正在使用react导航 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。道具“聚焦”或“导航”不会传递到 tabBarButton 函数中。我希望我的底部导航看起来像这里的图片

enter image description here

stack overflow How to add top border to tab that is active using react native bottom tabs
原文答案
author avatar

接受的答案

你可以像这样使用专注的道具

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