Moving screens, screen visible underneath - reactjs

When navigating from my VideoPlayer screen to a screen in my NestedDrawer, using this.props.navigation.navigate("TestYourself", { id }).
I briefly see the HomeScreen, underneath the screen I'm navigating too.
Is there anyway I can hide the HomeScreen underneath?
Home:{
screen: HomeScreen, // this is visible underneath
navigationOptions: ({ props }) => ({
header: props => <BasicHeader {...props} />
})
},
Drawer: {
screen: NestedDrawer, // navigate to screen in this stack
navigationOptions: ({ props }) => ({
header: () => null
})
},
VideoPlayer: {
screen: VideoPlayerScreen, //navigate from here
navigationOptions: ({ props }) => ({
header: props => <BasicHeader {...props} />
})
}
},
{
initialRouteName: "Home",
transparentCard: true
}
);
The yellow boxes and question text is from a screen in the NestedDrawer stack. The menu items behind it are on the HomeScreen. This lasts for about 3 seconds, then the screen behind disappears and it returns to normal:
AppNavigator:
const config = {
initialRouteName: "Home",
contentOptions: {
activeTintColor: "#e91e63",
itemStyle: {
flexDirection: "row-reverse"
}
},
drawerWidth: 300,
drawerPosition: "right"
};
const withHeader = (
screen: Function,
routeName: string,
Header
): StackNavigator =>
createStackNavigator(
{
[routeName]: {
screen,
navigationOptions: ({ routeName, props }) => ({
header: props => <Header {...props} />
})
}
},
{
transparentCard: true
}
);
const routes = {
.....
TestYourself: {
screen: withHeader(TestYourselfScreen, "Test Yourself", DrawerHeader)
},
....
Search: {
screen: withHeader(SearchScreen, "Search", DrawerHeader)
},
.....
};
const NestedDrawer = createDrawerNavigator(routes, config);
const MainStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: ({ props }) => ({
header: props => <BasicHeader {...props} />
})
},
Drawer: {
screen: NestedDrawer;,
navigationOptions: ({ props }) => ({
header: () => null
})
},
VideoPlayer: {
screen: VideoPlayerScreen,
navigationOptions: ({ props }) => ({
header: props => <BasicHeader {...props} />
})
}
},
{
initialRouteName: "Home",
transparentCard: true
}
);
export default createAppContainer(MainStack);

Related

how to hide bottomtabs when a route 2 levels deep is displayed

so when a certain screen is displayed, i want the bottom tabbar to disappear.
I am using react navigation.
when The insight detail adjustment screen is active, I want the bottomtabs to disappear.
Currently noting is working, only when I type bottomtabs {visible:false} inside the bottomtab navigator it works, but I need it nested one level deeper.
const incidentStack = createStackNavigator({
'incident Overview': {
screen: incidentOverview,
navigationOptions: ({navigation}) => ({
title: 'Pointbreak',
headerLeft: (
<TouchableOpacity onPress ={() => navigation.openDrawer()}>
<Image style={{marginLeft: 10}} source={require('../img/menu.png')}></Image>
</TouchableOpacity>
)
})
},
'insight detail adjustment': {
screen: InsightDetailAdjustment,
navigationOptions: ({navigation}) => ({
header: (
<HeaderTitleInsightDetailAdjustment navigation={navigation}/>
),
bottomTabs: {
visible: false
}
})
}
})
const AppNavigator = createBottomTabNavigator(
{
Insights: {
screen: InsightsStack,
navigationOptions: {
tabBarIcon: ({tintColor}) => (
<Icon name='chart-line-variant' size={30} color={tintColor}/>
),
}
},
Incidents: {
screen: incidentStack,
navigationOptions: ({navigation}) => ({
tabBarVisible: () => (
if(navigation.navigate('incident detail adjustment'){
return false
}else{
return true
})
),
tabBarIcon: ({tintColor}) => (
<Icon name='bullhorn-outline' size={30} color={tintColor}/>
),
})
},
You can try this:
InsightsStack.navigationOptions = ({ navigation }) => {
// hides tabNavigation starting from 2 screen deep in InsightsStack Stack
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarVisible
};
};

How to integrate the bottom navigators with drawer navigators

How to integrate the bottom navigators with drawer navigators and how to show the bottom navigations for all drawer screens. I did not get the bottom navigations except home screen
const BottomNavigator = createBottomTabNavigator(
{
HomeStack,
MoneyTransferStack,
// ReportStack,
BankAndFinanceStack,
NotificationStack,
})
const LeftNavigator = createDrawerNavigator({
Home: { screen: BottomNavigator },
BankAndFinanceScreen: {
screen: BankAndFinanceScreenDrawerStack,
navigationOptions: navOpt => ({
drawerLabel: ({ focused }) => (
<DrawerItem focused={focused} screen="BankAndFinanceScreenDrawerStack" title="Bank & Finance" />
)
})
},
ComplaintScreen: {
screen: ComplaintScreenStack,
navigationOptions: navOpt => ({
drawerLabel: ({ focused }) => (
<DrawerItem focused={focused} screen="ComplaintScreenStack" title="Complaints" />
)
})
},
});
const AppSwitchNavigator = createSwitchNavigator({
Main: {screen: LeftNavigator},
// Main: {screen: BottomNavigator},
ForgetPasswordScreen: { screen: ForgetPasswordScreen },
LoginScreen: {screen: LoginScreen},
RegisterScreen: { screen: RegisterScreen },
ComplaintForm: { screen: ComplaintForm },
});

onpress event for icon in TabNavigator (react native with react-navigation)

I have an icon that i include in a tab navigator as per below:
const SearchTabBarIcon = ({ tintColor }) => (
<IconMCI
name="account-search"
size={45}
color={tintColor}
onPress={() => console.log('HELP!!')}
/>
);
....then my tabNavigator looks like this:
const SignedInTabNav = TabNavigator(
{
Profile: {
screen: Profile,
navigationOptions: {
tabBarLabel: 'Me',
tabBarIcon: ProfileTabBarIcon,
},
},
Search: {
screen: Search,
navigationOptions: {
tabBarLabel: 'Search',
tabBarIcon: SearchTabBarIcon,
},
},
tabBarComponent: TabBarBottom,
animationEnabled: false,
},
);
The console.log is fired when I click the icon, however the native functionality of the tabNavigator is lost.
How can I fire the onPress event but also maintain the navigation functionality?
Ive heard I should perhaps "add the props of navigation to my component in the render".
The render function of App.js looks like this:
render() {
const Layout = createRootNavigator(this.props.isAuthenticated);
return (
<View style={{ flex: 1, backgroundColor: '#F8F8FF' }}>
<Layout />
</View>
);
}
....and the function createRootNavigator looks like this
const createRootNavigator = (authenticated = false) =>
createSwitchNavigator(
{
SignedInTabNav: {
screen: SignedInTabNav,
},
SignedOutStackNav: {
screen: SignedOutStackNav,
},
},
{
initialRouteName: authenticated ? 'SignedInTabNav' : 'SignedOutStackNav',
},
);
....so where/how do I add the navigation prop in the render for App.js?...and will it be passed down through createRootNavigator.....and further through createSwitchNavigator....and finally passed into SignedInTabNav (TabNavigator) where the Search icon is referenced?
You can simply use tabBarOnPress callback to handle press events as an additional option, like this:
const SignedInTabNav = TabNavigator(
{
Profile: {
screen: Profile,
navigationOptions: {
tabBarLabel: 'Me',
tabBarIcon: ProfileTabBarIcon,
},
},
Search: {
screen: Search,
navigationOptions: {
tabBarLabel: 'Search',
tabBarIcon: SearchTabBarIcon,
tabBarOnPress: ({ navigation, defaultHandler }) => {
console.log('this will be fired just before nagivation happens')
defaultHandler() // if you omit this, navigation will not happen
}
},
},
tabBarComponent: TabBarBottom,
animationEnabled: false,
},
);
Solution was to use the 'didFocus' event from reactNavigation
https://reactnavigation.org/docs/en/function-after-focusing-screen.html
componentDidMount() {
const { navigation } = this.props;
this.focusListener = navigation.addListener('didFocus', () => {
// The screen is focused
// Call any action
});
}

How to get title of screen in custom header component?

Hope it's ok.
I Can't understand how custom header it's supposed to work.
I just want to send static properties to my Header depending on which route is selected.
I have:
export default AppNavigator = StackNavigator({
Index:{
screen: BottomNavigator,
}
},{
navigationOptions: {
header: AppHeader,
},
headerMode:'float',
})
And my BottomNavigator is:
const BottomNavigator = TabNavigator({
TabMenu1: {
screen: () => <Text> Resumé </Text>,
navigationOptions: {
title: 'Resumé'
}
},
TabMenu2: {
screen: () => <Text> Sells </Text>,
navigationOptions: {
title: 'Sells'
}
},
},{
tabBarComponent: BottomNavigation
});
I'm expecting {props.title} in my custom header, is that right?
Additional info: My full route stack is:
AuthNavigator have a wrapper that is connected to redux and have:
const AuthNavigator = StackNavigator({
SignedIn: {
screen: MainNavigator
}
},{
headerMode:'none',
initialRouteName: 'SignedIn'
});
MainNavigator:
const MainNavigator = StackNavigator({
Drawer: {
screen: DrawerNav
},
}, {
headerMode:'none',
});
DrawerNav:
const DrawerNav = DrawerNavigator({
Menu1: {
screen: AppNavigator
},
}, {
contentComponent: DrawerNavigation,
drawerWidth: 300
});
AppNavigator and BottomNavigator are described above
for React Navigation 5 this works
props.scene.descriptor.options.title
You can specify title like this :
RouteName:
{
screen: RouteScreen,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title || 'StaticTitle'
})
}
Where navigation.state.params.title is the title you send as a params when you navigate (so if you want to add a variable for exemple). If you just want to use a static title, just use title: 'StaticTitle'
export const Navigator = StackNavigator(routes, {
headerMode: 'screen',
navigationOptions: ({ navigation }) => ({
header: props => <Header {...props} />,
}),
})
I did find a work around but it seems pretty verbose for what seems to be a common use case..
// Header.js
...
render() {
const { getScreenDetails, scene } = this.props
const details = getScreenDetails(scene)
return (
<View>
<Text>{details.options.title}</Text>
<View>
)
Resolved with a code extracted of Header.js file of react-navigation:
The right way to get the title inside a custom header is:
const sceneOptions = props.getScreenDetails(props.scene).options;
const sceneTitle = sceneOptions.title;
Thanks all!

using of Custom Tabs with StackNavigator?

I have list of users , each user has its display image in the list.
What I am trying is whenever user presses the display image , get redirected to his/her profile through stackNavigation .
CustomTabView:
const CustomTabView = ({ router, navigation }) => {
const { routes, index } = navigation.state;
const ActiveScreen = router.getComponentForState(navigation.state);
const routeNav = addNavigationHelpers({
...navigation,
state: routes[index],
});
const routeOptions = router.getScreenOptions(routeNav, 'tabBar');
return (
<View style={styles.container}>
<CustomTabBar
navigation={navigation}
activeRouteName={routes[index].routeName}
icon={routeOptions.tabBarIcon}
/>
<ActiveScreen
navigation={addNavigationHelpers({
...navigation,
state: routes[index]
})}
/>
</View>
);
};
StackNavigator: // goToProfile.js // also tried placing in index.anndroid.js but didnt found a way to export
const goToProfile = StackNavigator({
Profile: {
screen: Profile,
navigationOptions: ({ navigation }) => ({
title: `${navigation.state.params.person.name.first} ${navigation.state.params.person.name.last}`
})
},
})
custom tabs: //index.android.js
const CustomTabRouter = TabRouter(
{
Chat: {
screen: Chats,
path: ""
},
Status: {
screen: Contacts,
path: "notifications"
},
Camera: {
screen: Camera,
path: "settings"
}
},
{
initialRouteName: "Chat",
},
);
const CustomTabs = createNavigationContainer(
createNavigator(CustomTabRouter)(CustomTabView)
);
Also my component :
<TouchableOpacity
onPress = { () => this.props.navigation.navigate('Profile', { item } ) } >
<Avatar
source={{ uri: item.picture.thumbnail }}
/>
</TouchableOpacity>
Your Stack Navigator will look like this:
const ChatStack= StackNavigator({
Chat:{screen: Chat,
navigationOptions: {
header: null,
}},
Profile: {
screen: Profile,
navigationOptions: ({ navigation }) => ({
title: `${navigation.state.params.person.name.first} ${navigation.state.params.person.name.last}`,
tabBarVisible: false
// depending if you want to hide the tabBar on the profile page if not remove it.
})
},
})
Then Your customTab will take this shape:
const CustomTabRouter = TabRouter(
{
Chat: {
screen: ChatStack,
},
Status: {
screen: Contacts,
path: "notifications"
},
Camera: {
screen: Camera,
path: "settings"
}
},
.........
With those changes you should be able to navigate to Profile screen with your
this.props.navigation.navigate('Profile', { item } )
You want to dispatch a navigation action, not render a new stack - Although I'm not sure your navigators are properly constructed for this to succeed...
_goToProfile = (person) => {
<goToProfile navigate={this.props.navigation} />
}
should be
_goToProfile = (person) => {
this.props.navigation.navigate('Profile', person)
}

Resources