【问题标题】:React-Native - no header on one of the screen (Stack + Drawer Navigation)React-Native - 一个屏幕上没有标题(堆栈+抽屉导航)
【发布时间】:2021-04-06 18:10:22
【问题描述】:

我的导航文件如下。使用堆栈导航器注册的所有屏幕都有一个标题。使用 Drawer 导航器注册为第二个选项的一个屏幕根本没有标题 (OrdersScreen)。我也尝试在堆栈导航器下添加它的条目,但它没有改变任何东西。 OrderScreen 中的 setOptions 没有任何效果,因为没有显示任何标题。

import 'react-native-gesture-handler';
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createDrawerNavigator } from '@react-navigation/drawer';

import { Platform } from 'react-native';

import Colors from '../constants/Colors';

import ProductsOverviewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetailScreen from "../screens/shop/ProductDetailScreen";
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";


const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();


const AppNavigation = () => {
  return(
    <NavigationContainer>
      <Drawer.Navigator initialRouteName="ShopNavigation">
        <Drawer.Screen name="Products" component={ShopNavigation}/>
        <Drawer.Screen name="Orders" component={OrdersScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
};

const ShopNavigation = () => {
  return(
      <Stack.Navigator>
        <Stack.Screen
          name="Products"
          component={ProductsOverviewScreen}
          options={{
            title: 'All Products',
            headerStyle: {
              backgroundColor: Platform.OS === 'android' ? Colors.primary : ''
            },
            headerTintColor: Platform.OS === 'android' ? 'white' : Colors.primary,
            headerTitleStyle: {
              fontFamily: 'open-sans-bold'
            },
            headerBackTitleStyle: {
              fontFamily: 'open-sans'
            }
          }}
        />
        <Stack.Screen name="Product Details" component={ProductDetailScreen} />
        <Stack.Screen name="Cart" component={CartScreen} />
      </Stack.Navigator>
  );
};

export default AppNavigation;

订单界面如下:

import React, {useEffect} from 'react';
import {FlatList, View, Platform, Text, Button} from 'react-native';
import { useSelector } from 'react-redux';
import {HeaderButtons, Item} from "react-navigation-header-buttons";
import CustomHeaderButton from "../../components/UI/HeaderButton";

const OrdersScreen = (props) => {
  const orders = useSelector(state => state.orders.orders);

  useEffect(() => {
    props.navigation.setOptions({
      title: 'Your Orders',
      headerLeft: () => (
        <HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
          <Item
            title="Orders"
            iconName={Platform.OS === 'android' ? 'md-menu' : 'ios-menu'}
            onPress={() => props.navigation.toggleDrawer()}
          />
        </HeaderButtons>
        ),
    });
  },[])


  return(
    <View>
      <Text>Orders screens</Text>
      <Text>some text</Text>
      <Text>Yet another</Text>
      <Button title="toggle Drawer" onPress={() => props.navigation.toggleDrawer()} />
    </View>
  );
};


export default OrdersScreen; 

ProductsOverviewScreen 是 Stack 导航中的默认屏幕,可与标题按钮和标题图标配合使用。

import React, { useEffect } from 'react';
import { FlatList, Platform } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';
import ProductItem from "../../components/ProductItem";
import { addToCart } from "../../redux/cartSlice";
import { HeaderButtons, Item } from 'react-navigation-header-buttons';
import CustomHeaderButton from "../../components/UI/HeaderButton";

const ProductsOverviewScreen = ({ navigation }) => {
  const products = useSelector(state => state.products.availableProducts);
  const dispatch = useDispatch();

  useEffect(() => {
    navigation.setOptions({
      headerLeft: () => (
        <HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
          <Item
            title="Orders"
            iconName={Platform.OS === 'android' ? 'md-menu' : 'ios-menu'}
            onPress={() => navigation.toggleDrawer()}
          />
        </HeaderButtons>
      ),
      headerRight: () => (
        <HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
          <Item
            title="Cart"
            iconName={Platform.OS === 'android' ? 'md-cart' : 'ios-cart'}
            onPress={() => navigation.navigate('Cart')}
          />
        </HeaderButtons>
      )
      });
    }, [])


  return(
    <FlatList
      data={products}
      renderItem={({item}) =>
        <ProductItem
          image={item.imageUrl}
          title={item.title}
          price={item.price}
          onViewDetail={() => { navigation.navigate('Product Details', { productId: item.id, productTitle: item.title  })}}
          onAddToCart={() => dispatch(addToCart(item))}
        />
      }
      />
  );
};



export default ProductsOverviewScreen;

编辑:谢谢。我已经按照你说的做了(抽屉导航器中只有一个项目,并将 OrdersScreen 移动到 StackNavigator。我也向抽屉添加了自定义内容。现在唯一不起作用的是当我打开抽屉时从 OrdersScreen(通过抽屉自定义内容访问),当我点击“产品”(默认且只有抽屉项目)时,没有任何反应(抽屉隐藏但仍保留在 OrdersScreen 上)。这是更新的导航文件

import 'react-native-gesture-handler';
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem, } from '@react-navigation/drawer';

import { Platform } from 'react-native';

import Colors from '../constants/Colors';

import ProductsOverviewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetailScreen from "../screens/shop/ProductDetailScreen";
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";


const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();


const CustomDrawerContent = (props) => {
  return (
    <DrawerContentScrollView {...props}>
      <DrawerItemList {...props} />
      <DrawerItem label="Orders" onPress={() => props.navigation.navigate('Orders')} />
    </DrawerContentScrollView>
  );
}



const AppNavigation = () => {
  return(
    <NavigationContainer>
      <Drawer.Navigator initialRouteName="ShopNavigation" drawerContent={props => <CustomDrawerContent {...props} />}>
        <Drawer.Screen name="Products" component={ShopNavigation}/>
      </Drawer.Navigator>
    </NavigationContainer>
  );
};

const ShopNavigation = () => {
  return(
      <Stack.Navigator>
        <Stack.Screen
          name="Products"
          component={ProductsOverviewScreen}
          options={{
            title: 'All Products',
            headerStyle: {
              backgroundColor: Platform.OS === 'android' ? Colors.primary : ''
            },
            headerTintColor: Platform.OS === 'android' ? 'white' : Colors.primary,
            headerTitleStyle: {
              fontFamily: 'open-sans-bold'
            },
            headerBackTitleStyle: {
              fontFamily: 'open-sans'
            }
          }}
        />
        <Stack.Screen name="Product Details" component={ProductDetailScreen} />
        <Stack.Screen name="Cart" component={CartScreen} />
        <Stack.Screen name="Orders" component={OrdersScreen} />
      </Stack.Navigator>
  );
};

export default AppNavigation;

EDIT2: 所以现在我在 CustomDrawer 中有两个 DrawItem,它们在“所有产品”和“订单”中都可以正常工作。我遇到的问题是我无法摆脱默认的 DrawerNavigation 条目(不是自定义内容):

<Drawer.Screen name="ShopNavigation" component={ShopNavigation}/>

因为这意味着 Drawer.Navigator 没有任何子级。默认情况下,它必须默认为 StackNavigator,不是吗?您建议我应该让所有条目都来自 CustomDrawerContent。目前,抽屉里有以下物品:

  • ShopNavigation(默认,从“订单”中单击时不起作用。)
  • 所有产品(自定义内容,在任何地方都可以正常工作)
  • 订单(自定义内容,在任何地方都可以正常工作)

const CustomDrawerContent = (props) => {
  return (
    <DrawerContentScrollView {...props}>
      <DrawerItemList {...props} />
      <DrawerItem label="All Products" onPress={() => props.navigation.navigate('All Products')} />
      <DrawerItem label="Orders" onPress={() => props.navigation.navigate('Orders')} />
    </DrawerContentScrollView>
  );
}



const AppNavigation = () => {
  return(
    <NavigationContainer>
      <Drawer.Navigator drawerContent={props => <CustomDrawerContent {...props} />}>
        <Drawer.Screen name="ShopNavigation" component={ShopNavigation}/>
      </Drawer.Navigator>
    </NavigationContainer>
  );
};

const ShopNavigation = () => {
  return(
      <Stack.Navigator>
        <Stack.Screen
          name="All Products"
          component={ProductsOverviewScreen}
          options={{
            title: 'All Products',
            headerStyle: {
              backgroundColor: Platform.OS === 'android' ? Colors.primary : ''
            },
            headerTintColor: Platform.OS === 'android' ? 'white' : Colors.primary,
            headerTitleStyle: {
              fontFamily: 'open-sans-bold'
            },
            headerBackTitleStyle: {
              fontFamily: 'open-sans'
            }
          }}
        />
        <Stack.Screen name="Product Details" component={ProductDetailScreen} />
        <Stack.Screen name="Cart" component={CartScreen} />
        <Stack.Screen name="Orders" component={OrdersScreen} />
      </Stack.Navigator>
  );
};

【问题讨论】:

    标签: react-native react-navigation


    【解决方案1】:

    发生这种情况是因为标题被添加到堆栈导航器中的屏幕,而不是作为抽屉导航器一部分的屏幕。如果您希望标题显示在所有屏幕上,我建议您的抽屉导航器只有一个屏幕,它实际上是一个堆栈导航器,并且可以工作。在这种情况下,您还需要一个自定义抽屉组件来显示您想要的项目,因为默认情况下只有一个条目。

    【讨论】:

    • 谢谢。差不多了。请查看我的编辑。
    • 是的,这是因为该默认项是由抽屉导航器创建并重定向到它的子项。但在这种情况下,它的孩子不是屏幕,而是导航器。因此,您导航到导航器,但在导航器内部显示了另一个屏幕。您必须为抽屉上所需的每个项目创建自定义条目
    • 谢谢 - 我添加了另一个自定义项目,但我似乎无法删除默认/初始抽屉屏幕。它不能为空,对吗?
    • 对不起,我没看懂最后一部分。您能导航回“产品”屏幕吗?此外,我刚刚看到堆栈导航器和产品屏幕在各自的导航器中具有相同的名称。这可能是个问题。更改它们,使它们具有不同的名称。
    • 谢谢。我已经更改了名称。请参阅我的 EDIT2。问题是您建议为所有抽屉项目创建自定义项目。您不必在 Drawer.Navigator 中至少有一个默认的“正常”,而不是自定义 Drawer.Screen 元素? 见我的 EDIT2。
    猜你喜欢
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    • 2019-10-23
    • 2022-07-23
    • 1970-01-01
    相关资源
    最近更新 更多