Dynamically change bottom navigation icon based on drawer navigation icon - react-native

I want to dynamically change the icon of the bottom tab bar icon to the icon of the drawer page i change to. When the drawer open and i select cards page i want the payment icon to change from money to cards icon. Is this possible to achieve ? thanks
bottom tab
const bottomtab = createBottomTabNavigator(
{
home: {
screen: home,
navigationOptions: {
tabBarIcon: ({ tintColor, focused }) => <Icon name="home" color={tintColor} focused={focused} size={30} />,
},
},
payment: {
screen: paymentdrawerstack,
navigationOptions: ({ navigation }) => {
return{
tabBarIcon: ({ tintColor }) => <Icon name="money" color={tintColor} size={20} />,
}
},
},
},
drawer nav
const paymentdrawerstack = createDrawerNavigator(
{
balance: {
screen: balance,
navigationOptions: ({ navigation }) => {
return{
drawerIcon: ({ tintColor, focused }) => (
<Icon name="money" color={tintColor} focused={focused} size={20} />
),
drawerLabel: 'balance',
}
},
},
cards: {
screen: cards,
navigationOptions: ({ navigation }) => {
return{
drawerIcon: ({ tintColor, focused }) => (
<Icon name="cards" color={tintColor} focused={focused} size={20} />
),
drawerLabel: 'cards',
}
},
},

Try this, use this function to get the active route:
const getActiveRoute = route => {
if (!route.routes || route.routes.length === 0 || route.index >= route.routes.length) {
return route.routeName;
}
const childActiveRoute = route.routes[route.index];
return getActiveRoute(childActiveRoute);
}
And then in navigationOptions of payment, check what the active route is, change the icon accordingly, like so:
payment: {
screen: paymentdrawerstack,
navigationOptions: ({ navigation }) => {
const name = getActiveRoute(navigation.state) === 'cards' ? 'cards' : 'money';
return {
tabBarIcon: ({ tintColor }) => <Icon name={name} color={tintColor} size={20} />,
}
},
},

Related

react native bottom tab navigation version 4 icon problem

I have been trying to put an Icon in the bottom tab, I have been using the react navigation tabs version 4. I have tried to upgrade to version 5 but that's a different story.
The goal is just to include an icon but I'm just failing left and right. The documentation says to add it in the navigationOptions
HomeScreen.navigationOptions = ({navigation}) => {
return {
title: 'Get Me Goods',
headerStyle: HeaderStyle.headerStyle,
headerTintColor: HeaderStyle.headerTintColor,
headerTitleStyle: HeaderStyle.headerTitleStyle,
tabBarIcon: ({ color, size }) => <MaterialCommunityIcons name="home" color={color} size={size}/>,
headerLeft: () => <MenuImage
onPress={() => {
// navigation.openDrawer()
navigation.navigate('SignOut')
}}
/>
,
headerRight: () =>
<MenuImage
onPress={() => {
navigation.openDrawer()
}}
/>
}
}
and also tried it in the bottom tab navigator
const BottomTabMenu = createBottomTabNavigator(
{
Home: {
screen: Home,
options: {
tabBarLabel: 'Testing',
tabBarIcon: ({ color, size }) => <MaterialCommunityIcons name="home" color={color} size={size}/>
}
},
Me,
Search,
Messages,
Sell
},
{
initialRouteName: 'Home'
}
)
what else am I missing?
Got this figured out, just used the navigationOptions instead of options in the bottom tab bar configuration
const BottomTabMenu = createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
tabBarLabel: 'Testing',
tabBarIcon: ({ color, size }) => <MaterialCommunityIcons name="home" color={color} size={size}/>
}
},
Me,
Search,
Messages,
Sell
},
{
initialRouteName: 'Home'
}
)

How to fix invalid prop 'color' suplied to 'icon'?

I’m setting up a new component with an icon from the "react-native-vector-icons" and I got a yellow warning.
This is for a new feature of the icon
Dashboard: {
screen: DashboardStack,
navigationOptions: {
title: 'HOME',
tabBarOnPress: ({ navigation, defaultHandler }) => handleTabPress(navigation, defaultHandler),
tabBarIcon: ({ focused, tintColor }) => {
// HERE IS THE PROBLEM //
return <SSIcon name={'home'} size={20} color={focused ? GStyle.GREEN : Color(GStyle.BLACK).alpha(.45)} />
},
}
},
I expect for no yellow warning
You could try this code
<SSIcon name={'home'} size={20} color={focused ? "green" : "black"} />
have you tried separating the color instead?
const stackNav = createStackNavigator ({
Dashboard: {
screen: DashboardStack,
navigationOptions: {
title: 'HOME',
tabBarOnPress: ({ navigation, defaultHandler }) => handleTabPress(navigation, defaultHandler),
tabBarIcon: ({ focused, tintColor }) => <SSIcon name={'home'} size={20} color={tintColor} />
}
}}, {
tabBarOptions: {
activeTintColor:GStyle.GREEN,
inactiveTintColor: Color(GStyle.BLACK).alpha(.45)
})
in your application's root index.js add this line:
console.disableYellowBox = true;

React Navigation: Is it possible to navigate to the same screen from different stackNavigators?

I'm coding an app that uses react-navigation. My app has a bottom TabNavigator in which each tab consists of a stackNavigator, like so:
Routes.js:
const FirstStack = createStackNavigator({
First: {
screen: FirstScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const SecondStack = createStackNavigator({
Second: {
screen: SecondScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const ThirdStack = createStackNavigator({
Third: {
screen: ThirdScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const FourthStack = createStackNavigator({
Fourth: {
screen: FourthScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const FifthStack = createStackNavigator({
Fifth: {
screen: FifthScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
export const AppStack = createBottomTabNavigator(
{
First: {
screen: FirstStack,
navigationOptions: {
title: "First",
tabBarLabel: "First",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-home" color={tintColor} size={24} />
)
}
},
Second: {
screen: SecondStack,
navigationOptions: {
title: "Second",
tabBarLabel: "Second",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-clock" color={tintColor} size={24} />
)
}
},
Third: {
screen: ThirdStack,
navigationOptions: {
title: "Third",
tabBarLabel: "Third",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-fitness" color={tintColor} size={24} />
)
}
},
Fourth: {
screen: FourthStack,
navigationOptions: {
title: "Fourth",
tabBarLabel: "Fourth",
tabBarIcon: ({ tintColor }) => (
<Icon
name="ios-cloud-download"
color={tintColor}
size={24}
/>
)
}
},
Fifth: {
screen: FifthStack,
navigationOptions: {
title: "Fifth",
tabBarLabel: "Fifth",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-person" color={tintColor} size={24} />
)
}
}
},
{
initialRouteName: "First",
order: ["First", "Second", "Third", "Fourth", "Fifth"],
tabBarOptions: {
activeTintColor: "white",
inactiveTintColor: "grey",
style: {
backgroundColor: "#121212",
borderTopColor: "#303030"
}
}
}
);
Each stackNavigator inside the tabs in the tabNavigator has its own header so that I can customize the header for each tab, but all headers have a button which should navigate to the profile screen (in this example its the contact icon).
AppToolbar.js:
const appToolbar = props => {
return (
<View style={styles.toolbar}>
<Text style={styles.toolbarTitle}>Title</Text>
<TouchableOpacity onPress={...}>
<Icon
name="ios-contact"
color="grey"
size={30}
style={{ padding: 0, margin: 0, marginRight: 10 }}
/>
</TouchableOpacity>
</View>
);
};
What I want to do is that by pressing the contact icon the app should navigate to the profile screen, what I don't know is if its possible to define like a global route thats accesible from everywhere, Or do I have to add the profile screen to all the stackNavigators so that it is accesible from every screen in every stack?
Thanks in advance!
Found the answer here https://stackoverflow.com/a/50701940/1276438
Use a stackNavigator with the profile stack and the tabNavigator as children, making the tabNavigator the default route.

Functions are not valid as a React child (React-Native)

I can not wrap my head around and understand why am I given this warning, I am using two kinds of navigators ( tab navigator and stack navigator ), in App.js and I cannot seem to get them working correctly
App.js
export const Tabs = TabNavigator({
'FormScreen': {
screen: FormScreen,
navigationOptions: {
tabBarLabel: 'Contact Us',
tabBarIcon: ({ tintColor }) => <Icon name="ios-contact" type="entypo" size={28} color={tintColor} />
}
},
'ListScreen': {
screen: ListScreen,
navigationOptions: {
tabBarLabel: 'Contact List',
tabBarIcon: ({ tintColor }) => <Icon name="list" type="entypo" size={28} color={tintColor} />
}
}
});
export const NavigationScreen = () => {
return StackNavigator(
{
Tabs: {
screen: Tabs,
navigationOptions: {
gesturesEnabled: false
}
}
},
{
headerMode: "none",
mode: "modal"
}
);
};
export default class App extends React.Component {
render() {
return (
<NavigationScreen/>);
}
}

Force scrollview to re-render when closing a react-navigation modal?

I'm opening a modal, nested in a react-navigation TabNavigator.
This modal is used to add, say a teammate, to a Realm database.
When the new teammate is saved, I close the modal and "navigate" back to a ScrollView displaying all the teammates, retrieved from my Realm database.
My problem is that this ScrollView doesn't re-render when closing the modal.
I am not using Redux or any other state manager.
This is the code executed when saving a user:
onButtonPress() {
var teammate = new TeammateModel(this.firstname, this.lastname);
if (this.firstname && this.lastname) {
TeammateService.save(teammate);
this.props.navigation.goBack(null);
}
}
And this is the code of the for the component rendering the ScrollView:
export default class Team extends Component {
componentWillMount() {
teammates = TeammateService.findAll();
}
render() {
return (
<ScrollView>
<List>{teammates.map((teammate) => (
<ListItem
key={teammate.id}
title={`${teammate.firstname} ${teammate.lastname}`}
/>
))}
</List>
</ScrollView>
);
}
}
As requested here's also my routes.js where the navigation happens:
export const TeamStack = StackNavigator({
Team: {
screen: Team,
navigationOptions: ({ navigation }) => ({
headerTitle: 'Team',
headerRight: <Button title="Add" onPress={() => navigation.navigate('EditTeammate')} />
}),
},
})
export const EditTeammateStack = StackNavigator({
EditTeammate: {
screen: EditTeammate,
navigationOptions: ({ navigation }) => ({
headerTitle: 'Teammate',
headerLeft: <Button title="Cancel" onPress={() => navigation.goBack(null)} />
}),
}
})
export const NoteStack = StackNavigator({
EditNote: {
screen: EditNote,
navigationOptions: ({ navigation }) => ({
headerTitle: 'Edit note'
})
}
})
export const Tabs = TabNavigator({
EditNote: {
screen: NoteStack,
navigationOptions: ({ navigation }) => ({
header: { visible: true },
headerTitle: 'Edit note',
tabBarLabel: 'Notes',
tabBarIcon: ({ tintColor }) => <Icon name="list" size={20} color={tintColor} />
}),
},
Team: {
screen: TeamStack,
navigationOptions: ({ navigation }) => ({
header: { visible: true },
headerTitle: 'Team',
tabBarLabel: 'Team',
tabBarIcon: ({ tintColor }) => <Icon name="users" size={20} color={tintColor} />
}),
}
}, {
initialRouteName: 'Team',
});
export const Root = StackNavigator({
Tabs: {
screen: Tabs,
},
EditTeammate: {
screen: EditTeammateStack,
},
}, {
mode: 'modal',
headerMode: 'none'
});
export default Root;
I'm sure I'm doing one (or more) thing(s) wrong. But what? :)