繁体   English   中英

带有模态屏幕的堆栈中的嵌套标签栏(React Navigation v5)

[英]Nested Tab Bar in stack with modal screen (React Navigation v5)

我现在正在使用react-navigation v5。我有带 3 个屏幕'Home' Tab navigator 'Home' , 'Discover' , 'Profile' 我需要以这种方式进行导航,我可以在选项卡导航器的顶部完全呈现模态屏幕。在文档中,我没有找到如何从选项卡导航器执行此操作。 所以我决定在 Stack navigator 中嵌套 Tab navigator。 现在我有很多问题需要解决:

  1. 我如何在嵌套在堆栈中的选项卡导航器中显示每个选项卡的标题。

  2. 从“主页”中的视图显示模态屏幕。

  3. 由于我在 v5 之前使用打字稿,因此我将 v4 与NavigationInjectedProps一起使用。 我可以毫无问题地访问“Home”中的props.navigation嵌套组件,但现在我有未定义的props.navigation

MainNavigator.tsx

import HomeScreen from './Home/HomeScreen';
import DiscoverScreen from './Discover/DiscoverScreen';
import ProfileScreen from './profile/ProfileScreen';
import StreamsTabScreen from './Discover/tabview/tabScreens/StreamsTabScreen';
import { Image, Platform, View } from 'react-native';
import React from 'react';
import images from 'assets/images'
import DeviceInfo from 'react-native-device-info';
import VideoPlayer from '../../library/ui/videoPlayer/VideoPlayer';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

export type TabNavigationProp = {
    Home: undefined;            //
    Discover: undefined;        // Should be here all undefined ????
    Profile: undefined;         //
}

export type StacknavigationProp = {
    TabNavigator: undefined;      // Same here ???
    ModalPlayer: undefined;       //
}


const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();


const TabNavigator = () => {
    return (
        <Tab.Navigator>
            <Tab.Screen name='Home' component={HomeScreen}  />
            <Tab.Screen name='Discover' component={DiscoverScreen} />
            <Tab.Screen name='Profile' component={ProfileScreen} />
        </Tab.Navigator>
    );
};


const MainStackNavigator = () => {
    return (
        <Stack.Navigator mode='modal'>
            <Stack.Screen name='TabNavigator' component={TabNavigator} options={{ headerShown: false }} />
            <Stack.Screen name='ModalPlayer' component={VideoPlayer} />
        </Stack.Navigator>
    );
}

export default MainStackNavigator;

主屏幕.tsx

import { View, Text, StyleSheet, ScrollView } from "react-native";
import React from "react";
import StreamsScreen from '../../streamsScreen/StreamsScreen';
import VideoplayerScreen from '../../videoplayer/VideoplayerScreen';

import { CompositeNavigationProp } from '@react-navigation/native';
import { BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
import { StackNavigationProp } from '@react-navigation/stack';
import { TabNavigationProp, StacknavigationProp } from "../MainNavigator";

export type HomeScreenNavigationProps = CompositeNavigationProp<
  BottomTabNavigationProp<TabNavigationProp, 'Home'>,
  StackNavigationProp<StacknavigationProp>
  >; //           made props type from docs guide...

export default class HomeScreen extends React.Component<HomeScreenNavigationProps> {
  render() {
    console.log(this.props.navigate); //navigate is undefined... 
    return (
      <View style={styles.container}>
        <ScrollView style={styles.scrollView}>
          <View style={{ paddingBottom: 24 }}>
            <StreamsScreen navigate={this.props.navigation} />   //props.navigation does not exist
            <View style={styles.separator} ></View>
            <VideoplayerScreen />
          </View>
        </ScrollView>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  scrollView: {
    flex: 1,
    backgroundColor: '#0C2B33',
    paddingBottom: 20,
  },
  separator: {
    height: 1,
    backgroundColor: '#3D908E'
  }
});

StreamsScreen.tsx

import { View, Text, StyleSheet, Image, ActivityIndicator } from 'react-native';
import MainViewItem from '../../library/ui/MainViewItem';
import { NavigationState, SceneRendererProps, TabBar, SceneMap } from 'react-native-tab-view';
import images from 'assets/images';
import { Props as IndicatorProps } from '../../library/indicator/TabBarIndicator';
import { fetchStreamsPending, fetchStreamsRefresh } from '../../redux/actions/streamActions';
import { connect } from "react-redux";
import { RootState } from "src/redux/reducers";
import numberFormatter from "../../library/utils/numberFormatter";
import palette from 'assets/palette';
import getLanguage from '../../library/utils/isoLanguages';

import {
    StreamsState,
    StreamsPendingState,
    StreamsErrorState,
    StreamsPageOffsetState,
    Stream,
    StreamsRefreshState
} from '../../redux/store/types';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { HomeScreenNavigationProps } from '../main/Home/HomeScreen';


interface StreamsProps {
    fetchStreamsPending: typeof fetchStreamsPending;
    fetchStreamsRefresh: typeof fetchStreamsRefresh;
    streams: StreamsState
    pending: StreamsPendingState;
    error: StreamsErrorState;
    pageOffset: StreamsPageOffsetState;
    refresh: StreamsRefreshState;
}


type State = NavigationState<{
    key: string;
}>;

type Route = {
    key: string;
};

class StreamsScreen extends React.Component<StreamsProps & HomeScreenNavigationProps> { // HomeScreenNavigationProps not sure what right prop type i need here ....

...
    _onPressCard = () => {
        this.props.navigation.navigate('ModalPlayer'); //Property 'navigation' does not exist on type ...
        this.props.navigate('ModalPlayer'); //undefined here
    }
...

UPADE :我解决了导航问题,我没有使用打字稿实现所有导航逻辑......

应该做这样的事情:


export type TabParamList = {
    Home: undefined;
    Discover: undefined;
    Profile: undefined;
}

export type MainStackParamList = {
    TabNavigator: undefined;
    Stack2Nav: undefined;
    ModalPlayer: undefined;
}

export type MainStackParamList2 = {
    Home: undefined;
    Discover: undefined;
    Profile: undefined;
}

const Tab = createBottomTabNavigator<TabParamList>();
const RootStack = createStackNavigator<MainStackParamList>();


const TabNavigator = () => {
    return (
        <Tab.Navigator>
            <Tab.Screen name='Home' component={HomeScreen} />
            <Tab.Screen name='Discover' component={DiscoverScreen} />
            <Tab.Screen name='Profile' component={ProfileScreen} />
        </Tab.Navigator>
    );
};


const MainStackNavigator = () => {
    return (
        <RootStack.Navigator mode='modal'>
            <RootStack.Screen name='Tab' component={Tab} options={{ headerShown: false }} />
            <RootStack.Screen name='ModalPlayer' component={VideoPlayer} />
        </RootStack.Navigator>
    );
}

在 HomeScreen.tsx 中:

export type HomeScreenNavigationProp = CompositeNavigationProp<
  BottomTabNavigationProp<TabParamList, 'Home'>,
  StackNavigationProp<MainStackParamList>
  >;

  type Props = {
    navigation: HomeScreenNavigationProp;
  };

export default class HomeScreen extends React.Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <ScrollView style={styles.scrollView}>
          <View style={{ paddingBottom: 24 }}>
            <StreamsScreen navigation={this.props.navigation} />
            <View style={styles.separator} ></View>
            <VideoplayerScreen />
          </View>
        </ScrollView>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  scrollView: {
    flex: 1,
    backgroundColor: '#0C2B33',
    paddingBottom: 20,
  },
  separator: {
    height: 1,
    backgroundColor: '#3D908E'
  }
});

现在剩下的问题是模式屏幕显示标题,即使在根堆栈导航器中的 setup mode='modal' 之后,即使我从文档中的演示复制粘贴的代码。 在此处输入图片说明 在此处输入图片说明

看起来演示 gif 和代码没有显示相同的行为,我只是在我的模式屏幕选项中添加了{ headerShown: false }

   <RootStack.Screen
        name='ModalPlayer'
        component={VideoPlayer}
        options={{ headerShown: false }}
      />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM