嵌套TabNavigator

时间:2018-04-07 13:06:35

标签: react-native react-navigation

对于我正在处理的应用,我有一个相当复杂的导航流程要求。

我有一个底部标签栏,对于每个标签,我将有一个顶部标签栏,用于其他相关视图。

我已经工作了,但是在嵌套的“全部”标签的视频标签上,我需要在标题中添加一个搜索栏,在“收藏夹”标签上我将会有另一个自定义标题<右侧的“编辑”按钮。

如何实现此导航,同时允许React Navigation协调​​所有内容。见下图:

我不想做的是在MainNavigator级别禁用标头并为特定路由启用它。或者更糟糕的是将标题和标签栏嵌入各个容器中。

routes.js

import {
  StackNavigator,
  TabNavigator,
  DrawerNavigator
} from "react-navigation";
import Feed from "./containers/Feed";
import Auth from "./containers/Auth";
import News from "./containers/News";
import Videos from "./containers/Videos";
import FavouriteVideos from "./containers/FavouriteVideos";

const DashboardNavigator = TabNavigator(
  {
    Feed: {
      screen: Feed
    },
    News: {
      screen: News
    }
  },
  {
    tabBarPosition: "top"
  }
);

const VideoNavigator = TabNavigator(
  {
    Videos: {
      screen: Videos,
      navigationOptions: {
        title: "All"
      }
    },
    Favourites: {
      screen: FavouriteVideos
    }
  },
  {
    tabBarPosition: "top"
  }
);

const MainNavigator = TabNavigator(
  {
    Dashboard: {
      screen: DashboardNavigator,
      navigationOptions: ({}) => ({
        title: "Dashboard"
      })
    },
    Video: {
      screen: VideoNavigator,
      navigationOptions: ({}) => ({
        title: "Videos"
      })
    }
  },
  {
    swipeEnabled: false,
    animationEnabled: false,
    tabBarPosition: "bottom"
  }
);

const AuthenticatedNavigator = DrawerNavigator({
  App: {
    screen: MainNavigator
  }
});

const RootNavigator = StackNavigator({
  LoggedOut: {
    screen: Auth
  },
  Authenticated: {
    screen: AuthenticatedNavigator
  }
});

export default RootNavigator;

小吃

https://snack.expo.io/H1qeJrLiM

图片

Home

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

您可以将react-addListener功能与组合setParams结合使用,以实现所需的行为。

您可以侦听焦点和模糊事件,然后更改参数。然后在您的路由配置中,您可以查找此参数并确定要为标头呈现的内容。我changed your snack展示了我所建议的实例。

示例

const MainNavigator = TabNavigator(
  {
    Dashboard: {
      screen: DashboardNavigator,
      navigationOptions: ({}) => ({
        title: "Dashboard"
      })
    },
    Video: {
      screen: VideoNavigator,
      navigationOptions: ({navigation}) => {
        let title = 'Videos';
        navigation.state.routes.forEach((route) => {
          if(route.routeName === 'Videos' && route.params) {
            title = route.params.title;
          }
        });
        // I set title here but you can set a custom Header component
        return {
          tabBarLabel: 'Video',
          title
        }
      }
    }
  },
  {
    swipeEnabled: false,
    animationEnabled: false,
    tabBarPosition: "bottom"
  }
);
export default class Videos extends Component {
  constructor(props) {
    super(props);
    this.willFocusSubscription = props.navigation.addListener(
      'willFocus',
      payload => {
        this.props.navigation.setParams({title: 'All Videos'});
      }
    );
    this.willBlurSubscription = props.navigation.addListener(
      'willBlur',
      payload => {
        this.props.navigation.setParams({title: 'Just Videos'});
      }
    );
  }
  componentWillUnmount() {
     this.willFocusSubscription.remove();
     this.willBlurSubscription.remove();
  }
  render() {
    return (
      <View>
        <Text> Videos </Text>
      </View>
    );
  }
}