I am using react-navigation 3 versions with react native 0.59 version.
I am using switch navigation for the login code. Once I got login it's redirecting to the home screen and other navigation from home screen working fine but drawer icon not displaying.
My navigator.js
export const AppStack = createStackNavigator({
Home: {
screen: HomeScreen,
navigationOptions: {
headerRight:soundicon()
}
},
withdraw: {
screen: WithdrawScreen,
navigationOptions: {
headerRight:soundicon()
}
},
deposite: {
screen: DepositScreen,
navigationOptions: {
headerRight:soundicon()
}
},
money: {
screen: MoneyScreen,
navigationOptions: {
headerRight:soundicon()
}
}
});
export const drawermenu = createDrawerNavigator({
Home: AppStack,
})
export const AuthStack = createStackNavigator({
SignIn: {
screen: SignInScreen,
navigationOptions: {
header: null,
}
},
Signup: {
screen: SignupScreen,
navigationOptions: {
}
},
ForgotPassword: {
screen: ForgotPasswordScreen,
navigationOptions: {
}
}
});
export const AppNavigator = createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: drawermenu,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
});
export const AppNavigatorObj = createAppContainer(AppNavigator)
As it is you can open the drawer by sliding right,if you want to open it with a icon you have to make a header component and use it on screens you want. Heres a nice example of headers: https://react-native-training.github.io/react-native-elements/docs/header.html
Related
I'm in the process of creating a social media app and I've the following diagram of screen transition:
Main -> Profile -> Followers -> John's Profile -> John's Followers ->
Emily's Profile -> ....
How can I implement a flow like this? Currently my router implementation is buggy, I can not go nested, it returns the previous screen.
Here is the part of the router to express my problem:
const appStack = createStackNavigator(
{
[PROFILE_STACK]: { screen: profileStack },
[PROFILE_FOLLOWERS_STACK]: { screen: profileFollowersStack },
[PROFILE_FOLLOWINGS_STACK]: { screen: profileFollowingsStack }
},
{
initialRouteName: PROFILE_STACK,
headerMode: "none"
}
);
const profileStack = createStackNavigator(
{
[PROFILE]: {
screen: UserProfileScreen,
navigationOptions: () => ({
header: null
})
}
},
{
initialRouteName: PROFILE
}
);
const profileFollowersStack = createStackNavigator(
{
[PROFILE_FOLLOWERS]: {
screen: UserFollowersScreen,
navigationOptions: () => ({
header: null
})
}
},
{
initialRouteName: PROFILE_FOLLOWERS
}
);
const profileFollowingsStack = createStackNavigator(
{
[PROFILE_FOLLOWINGS]: {
screen: UserFollowingsScreen,
navigationOptions: () => ({
header: null
})
}
},
{
initialRouteName: PROFILE_FOLLOWINGS
}
);
export const goUserProfile = function(navigation, userId) {
const { navigate } = navigation;
navigate(PROFILE_STACK, {
userId: userId
});
};
export const goUserFollowers = function(navigation, userId) {
const { push } = navigation;
push(PROFILE_FOLLOWERS_STACK, {
userId: userId
});
};
export const goUserFollowings = function(navigation, userId) {
const { push } = navigation;
push(PROFILE_FOLLOWINGS_STACK, {
userId: userId
});
};
The problem was I was using navigate() method in my goUserProfile(), not push(). After using push(), my problem is solved.
Reference:
React Navigation V2: Difference between navigation.push and navigation.navigate
I have a bottomTabNavigator which looks like this.
const tabNavigator = createBottomTabNavigator({
[SCREEN1]: {
screen: StackNavigator1
},
[SCREEN2]: {
screen: StackNavigator2
},
[SCREEN3]: {
screen: SplashScreen
},
},
Now, how I do I go about creating a DrawerNavigator on each of the screens ? Creating on a normal screen is fairly straightforward. How to create it within a stackNavigator ?
its pretty straight forward. You set the DrawerNavigator as the screen component.
For example:
const dn1 = createDrawerNavigator({
[Screen1]: {
screen: Screen01
}
});
const dn2= createDrawerNavigator({
[Screen1]: {
screen: Screen02
}
});
const dn3 = createDrawerNavigator({
[Screen1]: {
screen: Screen03
}
});
const tabNavigator = createBottomTabNavigator({
[SCREEN1]: {
screen: dn1
},
[SCREEN2]: {
screen: dn2
},
[SCREEN3]: {
screen: dn3
},
}
This way you would have a separate DrawerNavigator for each tab.
When I specify drawerLockMode direactly with createStackNavigator it is not working.
const drawerStack = createStackNavigator({
HomeScreen: { screen: HomeScreen },
}, {
headerMode: 'screen',
navigationOptions: {
drawerLockMode:'locked-closed'
}
})
But when I use drawerStack variable to define navigationOptions, it is working.
drawerStack.navigationOptions = ({ navigation }) => {
drawerLockMode = 'locked-closed';
return {
drawerLockMode,
};
};
Am I doing any mistake when I am directly using it inside createStackNavigator?
Update
As #bennygenel suggested, we need to user drawerLockMode in drawerNavigator instead of stackNavigator. Here is what i have done.
const drawerNavigator = createDrawerNavigator({
drawerStack: drawerStack
}, {
contentComponent: DrawerComponent,
navigationOpions:{
drawerLockMode:'locked-closed'
}
})
But it is not working in this way also. The only way it is working is by using the const variable created using createStackNavigator or createDrawerNavigator
Try the following code, it's working for me:
const UserHome_StackNavigator = StackNavigator({
userHm: {
screen: UserHome,
navigationOptions: ({ navigation }) => ({
title: 'User screen title',
headerStyle: {
backgroundColor: 'white',
},
headerTintColor: 'black'
}),
},
});
UserHome_StackNavigator.navigationOptions = ({ navigation }) => {
let drawerLockMode = 'locked-closed';
//logic here to change conditionaly, if needed
return {
drawerLockMode,
};
};
in case someone need this:
const drawerNavigator = createDrawerNavigator({
drawerStack: drawerStack
}, {
contentComponent: DrawerComponent,
navigationOpions: ({navigation}) => {
let routeName = navigation.state.routes[navigation.state.routes.length-1].routeName;
if(['Animation', 'Splash', 'Intro', 'Login', 'Signup'].indexOf(routeName)>=0){
return {
drawerLockMode: 'locked-closed'
}
}
return {}
}
})
My issue is I tried to implement 2 type of Nagivation Type in my Apps, TabNavigation and StackNavigation, so I using a root StackNavigator, which has one route to myTabNavigator and one to my other StackNavigator(Code Snippet of App.js). However, when I navigate to View Screen which is SecondActivity.js there will be two header pop out. I try to use header:null on SecondActivity.js but it will cause both header gone.
Is there any way to remove only 1 of the header from the SecondActivity.js Screen?
App.js (using RootNavigator to combine Tab and Stack Navigation in this Apps)
const App = TabNavigator({
HomeScreen: { screen: HomeScreen },
ProfileScreen: { screen: ProfileScreen },
}, {
tabBarOptions: {
activeTintColor: '#7567B1',
labelStyle: {
fontSize: 16,
fontWeight: '600'
}
}
});
const Go = StackNavigator({
First: { screen: ProfileScreen },
Second: { screen: SecondActivity }
});
const rootNav = StackNavigator({
app: {screen: App},
go: {screen: Go},
});
export default rootNav;
ProfileScreen.js
static navigationOptions = {
tabBarLabel: 'View/Edit',
header: null
}
// This Line Used to Navigate to SecondActivity.js Screen
OpenSecondActivity(id) {
this.props.navigation.navigate('Second', { ListViewClickItemHolder: id });
}
// The ListView onPress will call the function above.
<ListView
automaticallyAdjustContentInsets={false}
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
renderRow={(rowData) => <Text style={styles.rowViewContainer}
onPress={this.OpenSecondActivity.bind(this, rowData.RecipeID)}> {rowData.RecipeName} </Text>}
/>
SecondActivity.js
static navigationOptions = {
title: 'View Details',
};
Each StackNavigator has its own header.
this is happening you are using nested stackNavigator, so one header is because of Go (stackNavigator), and another one is because of rootNav (stackNavigator).
The Go StackNavigation is unnecessary instead change the rootNav into this:
const App = TabNavigator({
HomeScreen: { screen: HomeScreen },
ProfileScreen: { screen: ProfileScreen },
}, {
tabBarOptions: {
activeTintColor: '#7567B1',
labelStyle: {
fontSize: 16,
fontWeight: '600'
}
}
});
const rootNav = StackNavigator({
app: {screen: App},
First: { screen: ProfileScreen },
Second: { screen: SecondActivity }
});
export default rootNav;
This is happening because of the fact that the tab navigator is being rendered within the stack navigator.
Create a util file, and put this method on it. It resets the stack and put tab navigator on top
const resetActivities = (navigation, rootPath,props) => {
const stackAction = NavigationActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: rootPath,params:props })],
});
navigation.dispatch(stackAction);
}
and pass the 'App', and the navigation object
React native Stack Navigator goes to the home page the default route (initialroutename) from every page of the app I want to go to previous pages from few pages and disable going to the back page from few pages. Back Handler is not even helping in this case. How can I achieve this
class AppNavigator extends Component {
constructor(props) {
super(props)
this.handleBackButtonClick = this.handleBackButtonClick.bind(this);
}
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonClick);
}
handleBackButtonClick() {
this.props.navigation.goBack();
return true;
}
render() {
return;
}
}
export default AppNavigator;
Code for Drawer Navigator. All routes are also defined here.
import React from "react";
import { DrawerNavigator } from "react-navigation";
import Home from "./components/home/";
import SideBar from "./components/sidebar";
import Dashboard from "./components/Dashboard/";
import Profile from "./components/Profile"
import Contact from "./components/Contact"
import Terms from "./components/terms"
import Links from "./components/Links"
import Register from "./components/Register"
import Discover from "./components/Discover/";
const Drawer = DrawerNavigator(
{
Home: { screen: Home },
Dashboard: { screen: Dashboard },
Discover: { screen: Discover }
Profile : {screen: Profile},
Contact: { screen: Contact},
Terms: { screen: Terms},
Links: { screen: Links},
Register: { screen: Register,
navigationOptions: {
title: "FirstPage",
header: {
left: null,
}
}, },
},
{
initialRouteName: "Home",
contentOptions: {
activeTintColor: "#e91e63"
},
drawerPosition: 'right',
contentComponent: props => <SideBar {...props} />
}
);
export default Drawer;
Why are you handling a back event? instead, use navigation reset property that will reset your route to 0 and user will never go back because stake is empty