Custom View as background for StackNavigator - react-native

I need use one image below stack navigator or something like this.
Into StackNavigator I can set backgroundColor, opacity (view style) etc. But no possibility to set one background image or custom view component. Also if set to each screen its not good for screen translation.
I was try to wrap like this:
<ImageBackground>
<MyStackNavigator/>
</ImageBackground/>
No results.
Can you help me? +1 for any try

I found a solution
Navigator:
const AuthStackNavigator = StackNavigator({
LANDING: {
screen: LandingScreen
},
SIGN_IN: {
screen: SignInScreen
},
{
mode: 'card',
cardStyle: { backgroundColor: 'transparent' },
transitionConfig: () => ({
containerStyle: {
backgroundColor: 'transparent',
}
}),
initialRouteName: 'LANDING',
}
);
Render:
render() {
return <ImageBackground
style={{
width: null,
height: null,
backgroundColor: 'transparent',
flex: 1,
}}
source={landing_background}
>
<AuthStackNavigator
ref='navigator'
/>
</ImageBackground>
}

Related

createBottomTabNavigator can't change tab from route 3 to route 2

I use createBottomTabNavigator in react navigation v3 and I have 3 route like that:
const Route = createBottomTabNavigator(
{
Home: {
screen: HomeRoute
}
Post: {
screen: PostRoute
},
Mark: {
screen: MarkRoute
},
}
)
but the problem or better say bug comes when I want to navigate from tab Mark to Post that doesn't navigate and change tab :(
any body can solve this problem? thanks!
For navigation, you use the navigate() function of the prop of the button you are using. For example,
If we define our createBottomTabNavigator to be,
export default createBottomTabNavigator(
{
Home: HomeScreen,
Settings: SettingsScreen,
}
);
We would move to the Settings tab using the navigate function of the button as seen below,
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button
title="Go to Settings"
onPress={() => this.props.navigation.navigate('Settings')}
/>
</View>
);
}
}
Here are more detailed examples, TAB-BASED-NAVIGATION
Define your route like this
const Route = createBottomTabNavigator(
{
Home: HomeRoute,
Post: PostRoute,
Mark: MarkRoute,
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
return <View/>
},
}),
tabBarOptions: {
activeTintColor: 'red',
inactiveTintColor: 'gray'
style: {
backgroundColor: 'black'
},
labelStyle: {
fontSize: 12
},
},
}
);

HeaderLeft onPress to open the drawer, undefined is not an object

I am having a problem with my line of code specifically with the headerLeft onPress. I wanted to put an icon where when pressed it will open the drawerNavigator of my simple application.
this is my AppNavigation.js
//DRAWER NAVIGATOR
const drawerNav = createDrawerNavigator({
JobFeed: {
screen: MainScreen,
navigationOptions: {drawerLabel: 'Job Feed',}
},
},
{
drawerPosition : "left", contentComponent: CustomDrawerComponent,
});
// Manifest of possible screens
const primaryNav = createStackNavigator({
LaunchScreen: {
screen: LaunchScreen,
navigationOptions: {
title: "Ty, Next",
headerTitleStyle: {
textAlign: 'center',
flex: 1,
fontFamily: 'CoreSansD65Heavy',
color: Colors.semiGray,
}
}
},
MainScreen: {
screen: MainScreen,
navigationOptions: {
title: "Ty, Next",
headerTitleStyle: {
textAlign: 'center',
flex: 1,
fontFamily: 'CoreSansD65Heavy',
color: Colors.semiGray,
marginBottom: 20,
}
}
},
},
{
// Default config for all screens
initialRouteName: 'MainScreen',
})
so here's the problem. In my MainScreen.js I put this code, whenever I press the button It is saying that undefined is not an object (evaluating _this2.props.navigation ) Please help me I am stuck on this particular matter..
static navigationOptions = ({ navigation }) => {
const { state } = navigation;
const {} = state;
return {
headerStyle:{
backgroundColor: "Transparent",
marginRight: 20,
marginLeft: 20,
},
headerLeft: (
<TouchableOpacity onPress={this.props.navigation.openDrawer()}>
<Icon name="bars" color={Colors.red} size={30}/>
</TouchableOpacity>
),
headerLeftStyle: styles.drawerIcon,
headerRight: (
<TouchableOpacity>
<Icon2 name="sc-telegram" color={Colors.red} size={30} />
</TouchableOpacity>
),
headerRightStyle: styles.planeIcon,
headerTransparent: true,
};
}
Also I can't even access my drawer navigator when swiping to right. Any Ideas why is this happening?
In your mainscreen.js is your component is class based component if it is try to create a fat arrow function instead of directly calling on onpress prop and call from that function and if your component is not class based make it first..!

Drawer Navigator with Stack in React Native in Header

I have a confusion regarding React Navigation. I need a Login screen which don't have Drawer and in rest of application, I need drawer Navigation.
I am looking for a solution where I can write code in a single place and applicable on whole application.
So I have created one stack navigator which contains the path of
createStackNavigator({
LoginRT:{
screen:Login
},
HomeRT:{
screen:Home
},
ContactRT:{
screen:Contact,
navigationOptions: {
headerRight: (
<Text></Text>
)
}
},
HaulerSelectionRT:{
screen:HaulerSelection
}
},
{
initialRouteName: 'LoginRT',
/* The header config from HomeScreen is now here */
defaultNavigationOptions : ({ navigation}) => ({
headerStyle: {
backgroundColor: "#3B9EC1",
color: 'white',
fontSize: 16,
},
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 20,
textAlign:"center",
flex:1
},
// headerRight: (
// <Icon
// size={30}
// name="bars"
// style={{ paddingRight: 5 }}
// onPress={() => navigation.openDrawer()}
// />
// ),
// headerLeft: <Text onPress={() =>
// navigation.navigate('LoginRT')}>Menu</Text>,
headerTintColor: "#fff",
animationEnabled: true
})
}
);
and one for Drawer Navigation
const DrawerStack = createDrawerNavigator(
{
LoginRoute: Login,
Hauler: HaulerSelection,
},
{
initialRouteName: 'LoginRoute',
drawerPosition: 'left',
// navigationOptions: {navigationOptions
// },
}
);
and then I register both in Appcontainer
const AppContainer = createAppContainer(MyRoutes,DrawerStack);
But DrawerNavigation is not working.
My doubt is, Is my approach is right? Or there is another way to achieve same.
Please help.
The header part is added by default and is avoidable.
You can use the following code to achieve this.
navigationOptions: {
header: null
}
This navigation options could either be screen specific or common to all screens.

CreateDrawerNavigator inside createStackNavigator

My issue is this: I can't seem to be able to add the hamburguer button on the left (to toggle the drawer) and also I cannot add the title to the drawer depending on the screen (for example, show 'Login' on header when it's on the login screen).
Brief explanation of the code:
The AppNavigation.js handles all the navigation for the app. Including the two drawers (LoggedDrawer and UnloggedDrawer).
They are inside a stack navigator (RootNavigator) and the RootNavigator is inside a container (react-navigation 3.0).
This is the code I have:
AppNavigation.js
const UnloggedDrawer = createDrawerNavigator(
{
Home: { screen: HomeScreen },
Login: { screen: LoginScreen },
SignUp: { screen: SignUpScreen }
}, {
drawerWidth: SCREEN_WIDTH * 0.6
}
)
const LoggedDrawer = createDrawerNavigator(
{
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen }
}, {
contentComponent: (props) => (
<View style={{ flex: 1 }}>
<SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
<DrawerItems {...props} />
<Button
color='red'
title='Logout'
onPress={() => { props.screenProps.logoutCurrentUser(props) }}
/>
</SafeAreaView>
</View>
),
drawerWidth: SCREEN_WIDTH * 0.6,
})
const RootNavigator = createStackNavigator({
Init: {
screen: Init,
navigationOptions: {
header: null,
},
},
UnloggedDrawer: { screen: UnloggedDrawer },
LoggedDrawer: { screen: LoggedDrawer }
},
{
mode: 'modal',
title: 'Main',
initialRouteName: 'Init',
transitionConfig: noTransitionConfig,
})
Init.js
componentWillReceiveProps(props) {
const { navigation } = props;
if (props.userReducer.isSignedUp) {
navigation.dispatch(StackActions.reset(
{ index: 0, key: null, actions: [NavigationActions.navigate({ routeName: 'LoggedDrawer' })] }
))
} else {
navigation.dispatch(StackActions.reset(
{ index: 0, key: null, actions: [NavigationActions.navigate({ routeName: 'UnloggedDrawer' })] }
))
}
}
On my screens, I have a navigationOptions for all of them just like this (the only difference is the icon), this is only part of the code just as an example:
export default class HomeScreen extends Component {
static navigationOptions = {
headerTitle: 'Home',
drawerIcon: () => (
<SimpleIcon
name="home"
color="rgba(110, 120, 170, 1)"
size={20}
/>
)};
}
So what I want to do is:
1. Add a hamburger icon to the header of all screens which will be used to toggle the drawer
2. Add the title on the middle of the header (also for all screens)
What I've tried:
Everything I could find on the internet and nothing seems to work.
Also, if my architecture is wrong, please point that out, if also there's a different way to achieve what I'm trying to do it's also accepted.
Thanks in advance. Please help.
So, answering my own question.
What I want is easily achieved by using react-native-elements.
They have a component called 'Header' that you can use on each screen to customize the header.
I added this to both of drawerNavigators and the stackNavigator.
headerMode: 'null'
Then for each screen I had to wrap the JSX code in React.Fragment, so it went like this:
<React.Fragment>
<Header
statusBarProps={{ barStyle: 'light-content' }}
barStyle="light-content"
leftComponent={
<SimpleIcon
name="menu"
color="#34495e"
size={20}
/>
}
centerComponent={{ text: 'HOME', style: { color: '#34495e' } }}
containerStyle={{
backgroundColor: 'white',
justifyContent: 'space-around',
}}
/>
</React.Fragment>
Leaving the answer in case anyone else have the same issue.

react-navigation: Full screen background with nested navigators

First of all, for anyone looking for a solution to show a full-screen background image with nested navigators, the code below will give a great headstart. I couldn't find any better resources and it took me a while to get this together.
Now onto the problem. The issue is that there seems to be no better way to show a consistent full-screen image background when using nested navigators which would be the most common use case for many apps. Ideally, you configure the background image for the RootStack and that would be it.
The problem with the code below is that the MenuStack will not show the background image even if wrapped inside a MenuStackWrapper and when trying to render the image in the Menu component itself, the image resizes differently and thus seems like it's moving.
const MenuStack = createStackNavigator(
{
Menu,
Log,
},
{
headerMode: 'none'
}
);
const MainStack = createBottomTabNavigator(
{
Now,
Today,
Menu: MenuStack
},
{
initialRouteName: 'Now',
tabBarOptions: {
style: {
backgroundColor: 'transparent'
}
}
}
);
class MainStackWrapper extends Component {
static router = MainStack.router;
render() {
return (
<ImageBackground source={require('./res/images/bgr.png')} style={{ width: '100%', height: '100%' }} imageStyle={styles.backgroundImage}>
<MainStack navigation={this.props.navigation} />
</ImageBackground>
);
}
}
const AppStack = createStackNavigator(
{
Main: MainStackWrapper,
Modal: ModalScreen
},
{
mode: 'modal',
headerMode: 'none',
cardStyle: {
backgroundColor: 'transparent'
}
}
);
const AuthStack = createSwitchNavigator({
SignIn,
SignUp,
ForgotPass
});
const RootStack = createSwitchNavigator(
{
AuthLoading,
Auth: AuthStack,
App: AppStack
},
{
initialRouteName: 'AuthLoading'
}
);
type Props = {};
export default class App<Props> extends Component {
render() {
return (
<ImageBackground source={require('./res/images/bgr.png')} style={{ width: '100%', height: '100%' }} imageStyle={styles.backgroundImage}>
<StatusBar barStyle="light-content" backgroundColor="transparent" translucent={true} />
<RootStack />
</ImageBackground>
);
}
}
const styles = StyleSheet.create({
backgroundImage: {
resizeMode: 'cover',
width: null,
height: null,
backgroundColor: 'transparent',
flex: 1,
flexDirection: 'column'
}
});