5
votes

Obtenez l'itinéraire actuel de l'écran actif du navigateur d'onglets dans React Navigation

Voici ma pile de navigation utilisant la navigation de réaction v3.2.1 :

  1. J'ai un commutateur de navigateur pour passer à la pile de navigation d'authentification et à la pile d'applications authentifiées.

  2. La pile d'applications est créée à l'aide d'un navigateur à onglet inférieur.

  3. Je souhaite utiliser un composant personnalisé pour le navigateur d'onglets.

Comment puis-je obtenir le nom de route actuel du navigateur d'onglets lorsque vous utilisez createBottomTabNavigator et un tabBarComponent personnalisé .

Par exemple:

  1. Supposons que la pile de navigation par onglets comporte 2 écrans de navigation, c'est-à-dire Accueil et Chat.
  2. Dans le BottomBar personnalisé, comment puis-je vérifier si le nom de route ciblé / actif / actuel est Accueil / Chat afin de pouvoir modifier le style des icônes respectivement?

AppContainer.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>
        )
    }
}

AppStack.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>
        )
    }
}

BottomBar.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

IconComponent.js

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

export default createAppContainer(switchStack)


0 commentaires

5 Réponses :


4
votes

l'objet de navigation de votre BottomBar personnalisé a un index qui contient l'index de l'écran actif actuel

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

navigation.state.index

Si l'écran d'accueil est actif >> navigation.state.index serait 0 Si l'écran de chat est actif >> navigation.state.index serait 1 ... etc


1 commentaires

Je suppose que cela pourrait fonctionner pour mon cas d'utilisation. J'enquête plus loin et je reviens bientôt.



1
votes

Vous pouvez avec 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 }
        },
    })
});

Ou mieux encore vous pouvez faire quelque chose comme ceci:

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


2 commentaires

J'ai déjà essayé cette méthode auparavant, mais au lieu de Accueil ou Chat , cette méthode ne renvoie que le nom de la route de la pile App , qui vient du haut pile de navigateur de commutateur de niveau.


le prop route a quitté navigation.state , c'est maintenant: ({navigation, route}) =>



3
votes

Plutôt que de définir un nouveau tabBarComponent complet pour les icônes, vous pouvez utiliser la propriété tabBarIcon pour définir les icônes. Vous pouvez trouver un exemple sur Documentation sur la navigation par onglets a >

Exemple (extrait de la documentation)

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',
    },
  }
);


1 commentaires

Oui, c'était comme ça que je travaillais avant. Mais comme je dois ajouter des fonctionnalités supplémentaires à la barre d'onglets (par exemple, un bouton d'action flottant), j'utilisais un composant personnalisé.



1
votes

Utilisation d'un composant fonctionnel avec React Navigation 5.x. Vous pouvez utiliser le hook useIsFocused .

const isFocused = useIsFocused();

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

Utilisation: dans chacun des écrans d'onglets que vous souhaitez détecter s'ils sont actuellement actifs ou ciblés. P >

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

Docs: https: // reactnavigation .org / docs / function-after-focus-screen /


0 commentaires

0
votes

Comme @Biskrem Muhammad l'a suggéré, cela fonctionne:

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


0 commentaires