React-Native - 屏幕之一上没有标题(堆栈 + 抽屉导航)

时间:2021-04-06 18:10:22

标签: react-native react-navigation

我的导航文件如下。使用堆栈导航器注册的所有屏幕都有一个标题。使用 Drawer 导航器注册为第二个选项的一个屏幕根本没有标题 (OrdersScreen)。我也尝试在 Stack navigator 下添加它的条目,但它没有改变任何东西。 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;

OrderScreen 如下:

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。我也向抽屉添加了一个自定义内容。现在唯一不起作用的是当我打开抽屉时从订单屏幕(通过抽屉自定义内容访问),当我点击“产品”(默认且仅抽屉项目)时,没有任何反应(抽屉隐藏但保留在订单屏幕上)。这是更新后的导航文件

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 中有两个 DrawItems,它们在“所有产品”和“订单”中都可以正常工作。我遇到的问题是我无法摆脱默认的 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>
  );
};

1 个答案:

答案 0 :(得分:0)

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