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

时间:2019-03-16 16:29:35

标签: reactjs react-native react-navigation

这是我使用反应导航 v3.2.1 的导航堆栈:

  1. 我有一个切换导航器,可以切换到Authentication导航堆栈和Authenticated App堆栈。

  2. 应用堆栈是使用底部标签导航器创建的。

  3. 我想为标签导航器使用自定义组件。

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

例如:

  1. 假设标签导航堆栈有2个导航屏幕,即“首页”和“聊天”。
  2. 在自定义的BottomBar内,如何检查focus / active / current 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>
        )
    }
}

5 个答案:

答案 0 :(得分:1)

在React Navigation 5.x中使用功能组件。您可以使用 useIsFocused 钩子。

import { useIsFocused } from "@react-navigation/native"; 

用法:在每个要检查的选项卡屏幕中,它们是当前处于活动状态还是处于焦点状态。

const isFocused = useIsFocused();

if (isFocused) {
  // the screen is currently focused
  // your code here
}

文档:https://reactnavigation.org/docs/function-after-focusing-screen/

答案 1 :(得分:0)

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

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

navigation.state.index

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

答案 2 :(得分: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 }
        },
    })
});

答案 3 :(得分:0)

您可以使用tabBarComponent属性来设置图标,而不必为图标设置全新的tabBarIcon。您可以在Tab Navigation Docs

上找到示例
  
      
  • tabBarIconnavigationOptions的属性,因此我们知道可以在屏幕组件上使用它,但是在这种情况下,选择将其放置   在createBottomTabNavigator配置中进行集中   图标配置,以方便使用。
  •   
  • tabBarIcon是被赋予focused statetintColorhorizontal参数的函数,它是一个布尔值。如果您采取   进一步浏览配置,您将看到tabBarOptions   以及activeTintColorinactiveTintColor。这些默认为   iOS平台为默认设置,但您可以在此处进行更改。的   传递给tintColor的{​​{1}}是   活动或非活动状态,具体取决于tabBarIcon状态(重点是   活性)。设备处于以下状态时,方向状态focused为true   在风景中,否则horizontal代表肖像。
  •   
  • 阅读full API reference,以获取有关false配置选项的更多信息。
  •   

示例 (来自文档)

createBottomTabNavigator

答案 4 :(得分:0)

正如@Biskrem Muhammad所建议的,此方法有效:

export function SignUp(props: TSignupProps) {
  const { navigation, route } = props;
  console.log('Im in screen:', route.name)
  .
  .
  .
}