I've been trying to build an application which will goto login screen after splash. Once the user logs in, it should be directed to a screen which has drawer navigation and tabs in it. I've been trying to implement this using react native expo. It's working fine in expo. But once I generate an APK and try to use it, after logging in it redirects to splash and login without showing any content. I've been using react-navigation package for navigating between the screens
My Navigator.js:
import React from 'react';
import { createAppContainer, createDrawerNavigator, createStackNavigator } from 'react-navigation';
import SplashScreen from '../screens/SplashScreen';
import Screen1 from '../screens/Screen1';
import Screen2 from '../screens/Screen2';
import Screen3 from '../screens/Screen3';
import MainDrawer from '../common/MainDrawer';
const LoginNavigator = createStackNavigator({
splash: SplashScreen
}, {
headerMode: 'none',
navigationOptions: {
headerVisibile: false,
}
});
const DrawerNavigator = createDrawerNavigator({
screen1: Screen1,
screen2: Screen2,
screen3: Screen3,
}, {
initialRouteName: 'screen1',
contentComponent: props => <MainDrawer {...props} />,
drawerWidth: 350,
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
const TotalNavigator = createStackNavigator({
loginStack: { screen: LoginNavigator },
drawerStack: { screen: DrawerNavigator },
}, {
headerMode: 'none',
initialRouteName: 'loginStack',
navigationOptions: {
headerVisible: false,
}
})
PrimaryNavigator = createAppContainer(TotalNavigator);
export default PrimaryNavigator;
My MainDrawer.js:
import React from 'react';
import { View, Text } from 'react-native';
import Image from 'react-native-remote-svg';
export default class MainDrawer extends React.Component {
constructor(props) {
super(props);
}
static navigationOptions = {
header: null,
};
render() {
return (
<View style={{ width: '100%', height: '100%', backgroundColor: '#2C2663' }}>
<View style={{ left: '7%', top: '10%' }}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<Image source={require('../assets/images/user_pic.svg')} />
<Text style={{ color: '#fff', fontSize: 25, flexDirection: 'row', left: '-28%', top: '10%' }}> SomeOne</Text>
</View>
<View style={{ width: '80%', borderBottomWidth: 1, borderBottomColor: '#C0C0C0', top: '20%' }} />
<Text style={{ color: '#C0C0C0', fontSize: 11, top: '30%' }}>
{`Some dummy text`}</Text>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', top: '40%' }}>
<Image style={{ width: 30, height: 30 }} source={require('../assets/images/icon.svg')} />
<Text style={{ color: '#fff', fontSize: 20, flexDirection: 'row', left: '-40%', top: '10%' }}
onPress={() => this.props.navigation.navigate('screen1')}> Screen 1 </Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', top: '50%' }}>
<Image style={{ width: 30, height: 30 }} source={require('../assets/images/icon2.svg')} />
<Text style={{ color: '#fff', fontSize: 20, flexDirection: 'row', left: '-42%', top: '10%' }}
onPress={() => this.props.navigation.navigate('screen2')}
> Screen 2</Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', top: '60%' }}>
<Image style={{ width: 30, height: 30 }} source={require('../assets/images/icon3.svg')} />
<Text style={{ color: '#fff', fontSize: 20, flexDirection: 'row', left: '-16%', top: '10%' }}
onPress={() => this.props.navigation.navigate('screen3')}
> Screen 3</Text>
</View>
</View>
</View>);
}
}
My SplashScreen.js:
import React from 'react';
import { Animated } from 'react-native';
import LottieView from 'lottie-react-native';
import LoginScreen from './LoginScreen.js';
export default class SplashScreen extends React.Component {
constructor(props) {
super(props);
this.state = { isAnimationVisible: true, animationProgress: new Animated.Value(0) };
this.homeScreen = this.homeScreen.bind(this);
}
static navigationOptions = {
header: null,
};
componentDidMount() {
Animated.timing(this.state.animationProgress, { toValue: 1, duration: 15000 })
.start(() => this.setState(s => ({ ...s, isAnimationVisible: false })));
}
//Navigate to Home screen
homeScreen() {
this.props.navigation.navigate('drawerStack');
}
render() {
if (this.state.isAnimationVisible) {
const interpolation = this.state.animationProgress.interpolate({ inputRange: [0, 1], outputRange: [0, 1] });
return (
<LottieView
source={require('../assets/animations/splash.json')}
progress={interpolation}
autoPlay
loop={false}
resizeMode='cover'
/>
);
}
else {
return (<LoginScreen goToHome={this.homeScreen} />);
}
}
}
My LoginScreen.js:
import React from 'react';
import { View, Image, Text, TextInput, KeyboardAvoidingView, ActivityIndicator } from 'react-native';
import { Button } from 'native-base';
import loginStyles from '../styles/loginStyles';
class LoginScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
};
this.onButtonPress = this.onButtonPress.bind(this);
}
static navigationOptions = {
header: null,
};
onButtonPress() {
let Users = list of users;
for (let i = 0; i < Users.length; i++) {
if ((Users[i].username == this.state.email) && (Users[i].password = this.state.password)) {
this.props.goToHome();
}
}
render() {
// On pressing login after giving credentials this.onButtonPress() is called
}
}
export default LoginScreen;
Can someone pointout where the issue is and suggest a fix? Thanks in advance.
Instead of creating TotalNavigator
as StackNavigator use SwitchNavigation
instead at the root, like this:
SwitchNavigator
|
|-SplashScreen # Create this as single screen no need to create Stack, initial screen
|
|-LoginNavigator
|
|-DrawerNavigator
Then in the LoginScreen
just navigate to MainDrawer
directly, it will handle the back press as well.