这是一个示例
TabBarShape.tsx:
import React, { useMemo } from "react";
import { Dimensions, Pressable, Text, View } from "react-native";
import { Svg, Path, Circle } from "react-native-svg";
const { NAVIGATION_BOTTOM_TABS_HEIGHT } = { NAVIGATION_BOTTOM_TABS_HEIGHT: 80 };
const { width: wWidth } = Dimensions.get("window");
function TabsShape({ tabWidth = 80, state, descriptors, navigation }) {
return (
<View style={{ height: NAVIGATION_BOTTOM_TABS_HEIGHT + 40 }}>
<View
style={{
flexDirection: "row",
zIndex: 1,
position: "absolute",
bottom: 0,
}}
>
{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, route.params);
}
};
const onLongPress = () => {
navigation.emit({
type: "tabLongPress",
target: route.key,
});
};
return (
<Pressable
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{
flex: 1,
alignItems: "center",
justifyContent: "center",
height: NAVIGATION_BOTTOM_TABS_HEIGHT,
}}
>
<Text style={{ color: isFocused ? "#673ab7" : "#222" }}>
{label}
</Text>
</Pressable>
);
})}
</View>
<View
style={{
zIndex: 0,
position: "absolute",
bottom: 0,
width: "100%",
height: "100%",
}}
>
<Svg
viewBox={`0 -40 ${wWidth} ${NAVIGATION_BOTTOM_TABS_HEIGHT + 60}`}
width="100%"
height={NAVIGATION_BOTTOM_TABS_HEIGHT + 60}
>
<Path fill="red" d="M0,0L160,0 M160,0L160.833,0C161.667,0,163.333,0,165.833,6C168.333,12,171.667,24,181.667,30C191.667,36,208.333,36,218.333,30C228.333,24,231.667,12,234.167,6C236.667,0,238.333,0,239.167,0L240,0 M240,0L430,0L430,80L0,80L0,0" />
<Circle
fill="#69b3a2"
stroke="black"
cx={wWidth / 2 - 30 / 2}
r="30"
/>
</Svg>
</View>
</View>
);
}
export { TabsShape };
App.tsx:
import * as React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { TabsShape } from "./TabBarShape";
function HomeScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
function MyTabBar({ state, descriptors, navigation }) {
return (
<View style={{ flexDirection: 'row', height: 200 }}>
{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,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
{label}
</Text>
</TouchableOpacity>
);
})}
</View>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator tabBar={(props) => <TabsShape {...props} />}>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}