在反应导航中获取选项卡导航器的当前活动屏幕路径

问题描述 投票:1回答:3

这是我使用react navigation v3.2.1的导航堆栈:

  1. 我有一个切换导航器切换到身份验证导航堆栈和Authenticated App堆栈。
  2. App堆栈使用底部选项卡导航器。
  3. 我想为tab导航器使用自定义组件。

使用createBottomTabNavigator和自定义tabBarComponent时,如何获取选项卡导航器的当前routeName。

例如:

  1. 假设标签导航堆栈有2个导航屏幕,即Home和Chat。
  2. 在自定义BottomBar中,如何检查聚焦/活动/当前routeName是否为Home / Chat,以便我可以分别更改图标的样式?

AppContainer.js

const switchStack = createSwitchNavigator({
    AuthLoading: AuthLoadingScreen,
    App: AppStack,
    Auth: AuthStack
}, {
    initialRouteName: 'AuthLoading',
})

export default createAppContainer(switchStack)

AppStack.js

const AppStack = createBottomTabNavigator({
    Home: {
        screen: HomeStack,
    },
    Chat: {
        screen: ChatStack
    },
}, {
    initialRouteName: 'Home',
    activeColor: '#f0edf6',
    inactiveColor: '#3e2465',
    shifting: false,
    barStyle: {
        backgroundColor: '#694fad',
    },
    labeled: false,
    tabBarComponent: ({navigation}) => <BottomBar navigation={navigation}/>
})

export default AppStack

BottomBar.js

export default class BottomBar extends React.Component {
    constructor(props) {
        super(props)
    }

    render() {
        return (
            <View style={styles.container}>
                <IconComponent routeName={'Home'}/>
                <IconComponent routeName={'Chat'}/>
            </View>
        )
    }
}

IconComponent.js

export default class IconComponent extends React.Component {
    constructor(props) {
        super(props)
    }

    ...

    render() {
        let IconComponent
        let iconName
        let iconSize = 25
        switch (this.props.routeName) {
            case 'Home':
                IconComponent = MaterialCommunityIcons
                // iconName = `home${focused ? '' : '-outline'}`;
                iconName = `home`;
                break
            case 'Chat':
                IconComponent = AntDesign
                iconName = `message1`
                iconSize = 22
                break
        }

        let tintColor = 'green'

        // if focused Home is current tab screen then change style eg. tint color.
        // similary if current tab screen is Chat, then change style.

        return (
                <Animated.View
                    style={[
                        styles.container,
                        {
                            opacity: this.opacity
                        }
                    ]}
                >
                    <IconComponent name={iconName} size={iconSize} color={tintColor}/>
                </Animated.View>
        )
    }
}
reactjs react-native react-navigation
3个回答
0
投票

自定义BottomBar的导航对象具有保存当前活动屏幕索引的索引

tabBarComponent: ({navigation}) => <BottomBar navigation={navigation}/>

navigation.state.index

如果主屏幕处于活动状态>> navigation.state.index将为0如果聊天屏幕处于活动状态>> navigation.state.index将为1 ...等


1
投票

而不是为图标设置一个完整的新tabBarComponent,您可以使用tabBarIcon属性来设置图标。你可以在Tab Navigation Docs上找到一个例子

  • tabBarIconnavigationOptions上的一个属性,所以我们知道我们可以在我们的屏幕组件上使用它,但是在这种情况下选择将它放在createBottomTabNavigator配置中以便集中图标配置以方便使用。
  • tabBarIcon是一个函数,给出focused statetintColorhorizontal param,这是一个布尔值。如果您在配置中进一步了解,您将看到tabBarOptionsactiveTintColor以及inactiveTintColor。这些默认为iOS平台默认值,但您可以在此处更改它们。传递给tintColortabBarIcon是活跃的或非活跃的,取决于focused状态(聚焦是活跃的)。设备处于横向时,方向状态horizontal为true,否则为false为纵向。
  • 有关full API reference配置选项的更多信息,请阅读createBottomTabNavigator

示例(来自文档)

export default createBottomTabNavigator(
  {
    Home: HomeScreen,
    Settings: SettingsScreen,
  },
  {
    defaultNavigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, horizontal, tintColor }) => {
        const { routeName } = navigation.state;
        let IconComponent = Ionicons;
        let iconName;
        if (routeName === 'Home') {
          iconName = `ios-information-circle${focused ? '' : '-outline'}`;
          // Sometimes we want to add badges to some icons. 
          // You can check the implementation below.
          IconComponent = HomeIconWithBadge; 
        } else if (routeName === 'Settings') {
          iconName = `ios-options${focused ? '' : '-outline'}`;
        }

        // You can return any component that you like here!
        return <IconComponent name={iconName} size={25} color={tintColor} />;
      },
    }),
    tabBarOptions: {
      activeTintColor: 'tomato',
      inactiveTintColor: 'gray',
    },
  }
);

0
投票

你可以用navigation.state.routeName

tabBarComponent: ({navigation}) => <BottomBar navigation={navigation} currentRouteName={navigation.state.routeName} />

或者更好的是你可以做这样的事情:

const TabNavigator = createBottomTabNavigator({
    Home: Home,
    Chat: Chat
},
{
    defaultNavigationOptions: ({ navigation }) => ({
        tabBarIcon: ({ focused, horizontal, tintColor }) => {
            if (navigation.state.routeName === 'Home') {
                return <Icon name='ios-home' size={30} color={tintColor} />
            } else if (navigation.state.routeName === 'Chat') {
                return <Icon name='ios-heart' size={30} color={tintColor} />
            }
        },
        tabBarOptions: {
            activeTintColor: '#2BEDBA',
            inactiveTintColor: '#FAFAFA',
            style: { backgroundColor: '#000', paddingTop: 5 }
        },
    })
});
© www.soinside.com 2019 - 2024. All rights reserved.