react-native - 如何修复我的导航堆栈,以便所有屏幕中的底部选项卡显示都需要身份验证?

我一直在更改底部选项卡的颜色,我通过在导航中切换一些堆栈位置来设法做到这一点。切换了 HomeTab,其中主屏幕以前是 HomeScreen,并将 homeScreen 移动到抽屉堆栈。但现在我的问题是,在 Homestack 中,所有其他屏幕都没有底部标签。我希望在所有屏幕上都有可用的底部标签,除了身份验证。此外,图像应仅显示在主屏幕中。我尝试将其添加到抽屉中,但它使图像消失。标签栏标题也没有显示在顶部。 (主屏幕不需要标题)

import React, { useEffect } from 'react'
import { Pressable, View, Image, Platform } from 'react-native'
// Navigation
import {
  DrawerActions,
  getFocusedRouteNameFromRoute,
  useNavigation,
  useRoute,
} from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import {
  createBottomTabNavigator,
  BottomTabBar,
} from '@react-navigation/bottom-tabs'
import { createDrawerNavigator } from '@react-navigation/drawer'
//import { SafeAreaView } from 'react-native-safe-area-context'
import { useSelector } from 'react-redux'
// Icons
import Ionicons from 'react-native-vector-icons/Ionicons'
// Screens
import LoginScreen from '../screens/authentication/login'
import RegisterScreen from '../screens/authentication/register'
import ForgotPasswordScreen from '../screens/authentication/forgotPassword'
import ConfirmScreen from '../screens/authentication/confirmEmail'
import ConfirmNewPassScreen from '../screens/authentication/confirmNewPassword'
import HomeScreen from '../screens/home'
import TrafficNoticesScreen from '../screens/notices/trafficNotices'
import UkkScreen from '../screens/ukk/faq'
import ProfileScreen from '../screens/profile'
import AddNewInsurance from '../screens/profile/addInsurance'
import AddNewCar from '../screens/profile/addCar'
import EditWorkplaceDetails from '../screens/profile/editWorkplaceDetails'
import AccidentsScreen from '../screens/accidents'
import CarAccidentScreen from '../screens/accidents/carAccident'
import PersonalAccidentScreen from '../screens/accidents/personalAccident'
import AssetsAccidentScreen from '../screens/accidents/assetsAccident'
import TrafficAccidentScreen from '../screens/accidents/trafficAccident'
import TowingScreen from '../screens/accidents/towing'
import GlassAccidentScreen from '../screens/accidents/glassAccident'
import RockOnWindowScreen from '../screens/accidents/rockOnWindow'
import CrackOnWindowScreen from '../screens/accidents/crackOnWindow'
import YesGlassInsuranceScreen from '../screens/accidents/yesGlassInsurance'
import NoGlassInsuranceScreen from '../screens/accidents/noGlassInsurance'
import TechnicalIssueScreen from '../screens/accidents/technicalIssue'
import CarBrokenScreen from '../screens/accidents/carBroken'
import BrokenCarTireScreen from '../screens/accidents/brokenCarTire'
import NearestServicesScreen from '../screens/accidents/nearestServices'
import AskOfferScreen from '../screens/offer'
import LocalServicesScreen from '../screens/services/localServices'
import ServicesScreen from '../screens/services/services'
import AdsScreen from '../screens/ads'
import NoticesScreen from '../screens/notices'
import Notices from '../screens/notices/notices'
import InsuranceCompaniesScreen from '../screens/insurances'
import Info from '../screens/info'
import Settings from '../screens/settings/settings'
import OnBoardingScreen from '../screens/onboarding'
import DrawerMenu from '../navigation/Drawer'
// Colors
import colors from '../styles/Colors'

// Main tab navigation
const Tab = createBottomTabNavigator()

const CustomBottomTab = (props) => {
  return <BottomTabBar {...props} />
}

const HomeTab = () => {
  return (
    <Tab.Navigator
      tabBar={(props) => <CustomBottomTab {...props} />}
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused, color, size }) => {
          let iconName

          if (route.name === 'Koti') {
            iconName = focused ? 'ios-home' : 'ios-home-outline'
          } else if (route.name === 'Palvelut') {
            iconName = focused ? 'ios-pin' : 'ios-pin-outline'
          } else if (route.name === 'Ukk') {
            iconName = focused ? 'ios-help-circle' : 'ios-help-circle-outline'
          } else if (route.name === 'Omat tiedot') {
            iconName = focused
              ? 'ios-person-circle'
              : 'ios-person-circle-outline'
          }
          // You can return any component that you like here!
          return <Ionicons name={iconName} size={size} color={color} />
        },
        tabBarActiveTintColor: colors.white_087,
        tabBarInactiveTintColor: colors.gray_066,
        tabBarActiveBackgroundColor: colors.black_021,
        tabBarStyle: {
          display: 'flex',
          backgroundColor: colors.black_015,
          borderTopColor: colors.black_015,
        },
        tabBarHideOnKeyboard: true,
        headerShown: false,
        headerTransparent: false,
        headerTitleAlign: 'center',
        headerTitleStyle: { color: colors.black, fontSize: 16 },
        // headerRight: () => (
        //   <>
        //     <Pressable
        //       onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
        //     >
        //       <Ionicons
        //         testID='DrawerMenu'
        //         name='ellipsis-horizontal-outline'
        //         size={40}
        //         color={colors.black}
        //       />
        //     </Pressable>
        //   </>
        // ),
      })}
    >
      <Tab.Screen
        name='Koti'
        component={HomeScreen}
        options={{
          headerTitle: 'Vahingonsattuessa',
          headerShown: false,
        }}
      />
      <Tab.Screen
        name='Palvelut'
        component={LocalServicesScreen}
        options={{
          headerTitle: 'Palvelut',
          headerTitleStyle: { color: colors.white_087 },
          headerBackgroundContainerStyle: { backgroundColor: colors.black_015 },
        }}
      />
      <Tab.Screen
        name='Ukk'
        component={UkkScreen}
        options={{
          headerBackgroundContainerStyle: { backgroundColor: colors.white },
          headerTitle: 'Usein kysytyt kysymykset',
        }}
      />
      <Tab.Screen
        name='Omat tiedot'
        component={ProfileStack}
        options={{ headerShown: false }}
      />
    </Tab.Navigator>
  )
}

const Drawer = createDrawerNavigator()

const DrawerNav = () => {
  const completed = useSelector((state) => state.boardingReducer.completed)

  return completed === false ? (
    <BoardingStack />
  ) : (
    <Drawer.Navigator
      drawerContent={(props) => <DrawerMenu {...props} />}
      screenOptions={{
        headerShown: false,
        drawerStyle: { backgroundColor: colors.black_007 },
      }}
    >
      <Drawer.Screen name='HomeTab' component={HomeStack} />
    </Drawer.Navigator>
  )
}

const Boarding = createNativeStackNavigator()

const BoardingStack = () => {
  return (
    <Boarding.Navigator>
      <Boarding.Screen
        name='Boarding'
        component={OnBoardingScreen}
        options={{ headerShown: false }}
      />
    </Boarding.Navigator>
  )
}

const Home = createNativeStackNavigator()

const HomeStack = () => {

  return (
    <Home.Navigator
      screenOptions={({ navigation, route }) => {
        return {
          animationEnabled: false,
          headerBackTitleVisible: false,
          headerTintColor: colors.gray_066,
          headerTitleAlign: 'center',
          headerTitleStyle: {
            color: colors.white_087,
            fontSize: 16,
          },
          headerTransparent: false,
          headerStyle: { backgroundColor: colors.black_015 },
          headerLeft: () => {
            if (route.name == 'Koti') {
              return  <Image
              resizeMode='contain'
              style={{
                width: 200,
                height: Platform.OS == 'ios' ? 35 : 50,
                alignSelf: 'center',
                marginLeft: Platform.OS == 'ios' ? -40 : 0,
              }}
              source={require('../images/vh_logo_neg.png')}
            />
            }
          },
          headerRight: () => (
            <>
              <Pressable
                onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
              >
                <Ionicons
                  testID='DrawerMenu'
                  name='ellipsis-horizontal-outline'
                  size={40}
                  color={colors.gray_066}
                />
              </Pressable>
            </>
          ),
        }
      }}
    >
      <Home.Screen
        name='HomeScreen'
        component={HomeTab}
        options={{
          headerTitle: '',
          headerShadowVisible: false,
        }}
      />
      <Home.Screen name='Vahinkopalvelut' component={AccidentsScreen} />
      <Home.Screen
        name='Ajoneuvovahinko / vika'
        component={CarAccidentScreen}
      />
      <Home.Screen name='Henkilövahinko' component={PersonalAccidentScreen} />
      <Home.Screen name='Omaisuusvahinko' component={AssetsAccidentScreen} />
      <Home.Screen
        name='Liikennevahinko / muu vahinko'
        component={TrafficAccidentScreen}
      />
      <Home.Screen name='Hinaus' component={TowingScreen} />
      <Home.Screen name='Lasivahinko' component={GlassAccidentScreen} />
      <Home.Screen
        name='Tuulilasiin tuli kivi / nasta'
        component={RockOnWindowScreen}
      />
      <Home.Screen
        name='Tuulilasissa on halkeama'
        component={CrackOnWindowScreen}
      />
      <Home.Screen
        name='Lasivakuutus kyllä'
        component={YesGlassInsuranceScreen}
      />
      <Home.Screen name='Lasivakuutus ei' component={NoGlassInsuranceScreen} />
      <Home.Screen name='Tekninenvika' component={TechnicalIssueScreen} />
      <Home.Screen name='Tekninen vika' component={CarBrokenScreen} />
      <Home.Screen name='Huoltokorjaamot' component={NearestServicesScreen} />
      <Home.Screen name='Rengas rikko' component={BrokenCarTireScreen} />
      <Home.Screen
        name='Rengas rikki ei hinausta'
        component={NearestServicesScreen}
        options={{
          headerTitle: 'Rengasliikkeet',
        }}
      />
      <Home.Screen name='Määräaikaishuolto' component={NearestServicesScreen} />
      <Home.Screen name='Pyydä tarjous' component={AskOfferScreen} />
      <Home.Screen
        name='Paikalliset palvelut'
        component={LocalServicesScreen}
      />
      <Home.Screen name='Ajoneuvopalvelut' component={ServicesScreen} />
      <Home.Screen name='Henkilöpalvelut' component={ServicesScreen} />
      <Home.Screen name='Omaisuuspalvelut' component={ServicesScreen} />
      <Home.Screen name='Tarjoukset' component={AdsScreen} />
      <Home.Screen name='Tiedotteet' component={NoticesScreen} />
      <Home.Screen name='Muut Tiedotteet' component={Notices} />
      <Home.Screen name='Liikennetiedotteet' component={TrafficNoticesScreen} />
      <Home.Screen name='Info' component={Info} />
      <Home.Screen
        name='Vakuutus yhtiöt'
        component={InsuranceCompaniesScreen}
      />
      <Home.Screen
        name='Asetukset'
        component={Settings}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Kirjaudu'
        component={LoginScreen}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Rekisteröidy'
        component={RegisterScreen}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Resetoi salasana'
        component={ForgotPasswordScreen}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Vahvista tili'
        component={ConfirmScreen}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Vaihda salasana'
        component={ConfirmNewPassScreen}
        options={{
          headerTitleStyle: { color: colors.gray_066, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
    </Home.Navigator>
  )
}

const Profile = createNativeStackNavigator()
const ProfileStack = () => {
  const navigation = useNavigation()
  const route = useRoute()

  useEffect(() => {
    const tabHiddenRoutes = [
      'Asetukset',
      'Kirjaudu',
      'Rekisteröidy',
      'Resetoi salasana',
      'Vahvista tili',
      'Vaihda salasana',
    ]

    if (tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))) {
      navigation.setOptions({ tabBarStyle: { display: 'none' } })
    } else {
      navigation.setOptions({ tabBarStyle: { display: 'flex' } })
    }
  }, [navigation, route])

  return (
    <Profile.Navigator>
      <Profile.Screen
        name='Omat Tiedot'
        component={ProfileScreen}
        options={{
          headerTitle: 'Omat tiedot',
          headerTitleAlign: 'center',
          headerShadowVisible: false,
          headerTransparent: false,
          headerTitleStyle: { color: colors.black, fontSize: 16 },
          headerRight: () => (
            <>
              <Pressable
                onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
              >
                <Ionicons
                  testID='DrawerMenu'
                  name='ellipsis-horizontal-outline'
                  size={40}
                  color={colors.black}
                />
              </Pressable>
            </>
          ),
        }}
      />
      <Profile.Screen
        name='Lisää vakuutus'
        component={AddNewInsurance}
        options={{
          headerLeft: null,
          headerRight: null,
          headerBackTitle: 'Lisää vakuutus',
          headerTitleAlign: 'center',
          headerShadowVisible: false,
        }}
      />
      <Profile.Screen
        name='Lisää ajoneuvo'
        component={AddNewCar}
        options={{
          headerLeft: null,
          headerRight: null,
          headerBackTitle: 'Lisää ajoneuvo',
          headerTitleAlign: 'center',
          headerShadowVisible: false,
        }}
      />
      <Profile.Screen
        name='Työpaikka tiedot'
        component={EditWorkplaceDetails}
        options={{
          headerLeft: null,
          headerRight: null,
          headerBackTitle: 'Työpaikka tiedot',
          headerTitleAlign: 'center',
          headerShadowVisible: false,
        }}
      />
    </Profile.Navigator>
  )
}

// Root navigation stack that includes tab navigation after you are signed/registered in
const Root = createNativeStackNavigator()

const Navigation = () => {
  return (
    <Root.Navigator
      screenOptions={() => {
        return {
          headerTitleAlign: 'center',
        }
      }}
    >
      <Root.Screen
        name='Vahginonsattuessa'
        component={DrawerNav}
        options={() => {
          return {
            headerShown: false,
            headerStyle: {
              backgroundColor: colors.white,
              shadowColor: 'transparent',
            },
          }
        }}
      />
    </Root.Navigator>
  )
}

export default Navigation

回答1

您可以创建一个堆栈并将其放在选项卡导航器中。

例如:

import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function MyStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home" component={Home} />
      <Stack.Screen name="Profile" component={Profile} />
      <Stack.Screen name="Settings" component={Settings} />
    </Stack.Navigator>
  );
}
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function MyTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={MyStack} /> // Register the stack
      <Tab.Screen name="Settings" component={SettingsScreen} />
    </Tab.Navigator>
  );
}

相似文章

最新文章