如何在反应导航的底部选项卡中拥有自定义视图,检查图像

问题描述 投票:0回答:1

Custom Tab Image

我想要一个自定义选项卡视图,其中中间选项卡在下面缩进以实现完整的波浪形状,我尝试使用图像背景作为底部选项卡,但我还没有走得太远

reactjs react-native navigation react-navigation
1个回答
0
投票

这是一个示例

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>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.