如何使用反应本机底部选项卡将顶部边框添加到活动选项卡
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>
)
}
我正在使用反应导航 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>
)
}