ReactNative Navigation Example

React Native Navigation

React Native Navigation provides 100% native platform navigation on both iOS and Android for React Native apps.

In this tutorial I will demonstrate you how to install react-native-navigation in your app, work with singlescreen (without tab), work with tabbased screen, Navigating forward, Navigating backward.

Get GITHUB code from HERE.

 

 

Adding React Native Navigation To Android

  • Install react-native-navigation latest stable version.
npm install --save react-native-navigation@latest
  • Add the following in android/settings.gradle.
include ':react-native-navigation'
project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/android/app/')
  • Update project dependencies in android/app/build.gradle.
android {

compileSdkVersion 25 

buildToolsVersion "25.0.1"

... }

dependencies {

compile fileTree(dir: "libs", include: ["*.jar"]) 

compile "com.android.support:appcompat-v7:23.0.1" 

compile "com.facebook.react:react-native:+" 

compile project(':react-native-navigation') 

}
  • In MainActivity.java it should extend  com.reactnativenavigation.controllers.SplashActivity  instead of ReactActivity.
import com.reactnativenavigation.controllers.SplashActivity; 

public class MainActivity extends SplashActivity { 

}

If you have any react-native related methods, you can safely delete them.

  • In MainApplication.java , add the following
//react-native-navigation
import com.reactnativenavigation.NavigationApplication;
public class MainApplication extends NavigationApplication {

  @Override
  public boolean isDebug() {
    // Make sure you are using BuildConfig from your own application
    return BuildConfig.DEBUG;
  }

  protected List<ReactPackage> getPackages() {
    // Add additional packages you require here
    // No need to add RnnPackage and MainReactPackage
    return Arrays.<ReactPackage>asList(
             //eg..new VectorIconsPackage()
    );
  }

  @Override
  public List<ReactPackage> createAdditionalReactPackages() {
    return getPackages();
  }

//if you are using index.js as your entry point instead of index.ios.js and index.android.js
 //(it is the default since React Native 0.49).  

@Override public String getJSMainModuleName() { 
return "index"; } 
}

Make sure that isDebug and createAdditionalReactPackages methods are implemented.

  • Update AndroidManifest.xml and set android:name value to .MainApplication
<application

android:name=".MainApplication"

... />

Registering and Rendering a Screen

Before loading screen into our app  firstly we must  have to register the screen using Navigation.

import { Navigation } from "react-native-navigation";
import MainScreen from "./src/screens/MainScreen/MainScreen";
// Register Screens
Navigation.registerComponent(
  "navigation-example.MainScreen",
  () => MainScreen);

Now there is no need to write:

AppRegistry.registerComponent('NavigationExample', () => App);   in index.js

Now Navigation object provided by the react-native-navigation will tell us our react app which screen is to render
first.Here I am starting App using startSingleScreenApp you can also use startTabBasedApp if you want tabs.

// Starting App

Navigation.startSingleScreenApp({
  screen: {
    screen: "navigation-example.MainScreen",
    title: "Entertainment"
  }
});

Adding a Tab Screen (Tabs Navigation)

For Tabs Navigation we use startTabBasedApp() inside this function we define array of tabs using tabs property.We can also use tabStyle(ios),appStyle (android) for tab styling.

Note:  Tabs without icon works on ios but not  on android.For android we must have to define icon property.For more detail you can visit here.

Here in this tutorial  I have used react-native-vector-icons. For installation you can visit to my this tutorial.

import { Navigation } from 'react-native-navigation';
import { Platform } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';

const startTabs = () => {
    Promise.all([
        Icon.getImageSource(Platform.OS === 'android' ? "md-videocam" : "ios-videocam", 30),
        Icon.getImageSource(Platform.OS === 'android' ? "md-musical-notes" : "ios-musical-notes", 30),
        Icon.getImageSource(Platform.OS === 'android' ? "md-easel" : "ios-easel", 30)
         
    ]).then(sources => {
        Navigation.startTabBasedApp({
            tabs: [
                {
                    screen: "navigation-example.Movies",
                    label: "Movies",
                    title: "Movies",
                    icon: sources[0],


                },
                {
                    screen: "navigation-example.Plays",
                    label: "Plays",
                    title: "Plays",
                    icon: sources[1],


                },
                {
                    screen: "navigation-example.Events",
                    label: "Events",
                    title: "Events",
                    icon: sources[2],

               }
            ],
            //tabstyle only works for ios for android we have to use appstyle
            tabsStyle: {
                tabBarSelectedButtonColor: "orange"
            },

            appStyle: {
                tabBarSelectedButtonColor: "orange"
            }

        });
    });
};

export default startTabs;

The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

The Promise.all(iterable) method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises.

An iterable object such as an Array or String

Pushing Pages (Navigating Forward)

On button click or view  press if you  want to navigate to a new page ,navigator as a prop provided by the react-native make it possible.

onItemPressedHandler= (name,image)=>{

this.props.navigator.push({
      screen: "navigation-example.MovieDetail",
      title: name,
      passProps: {
        movieName: name,
        movieImage: image
      }
    });
}

Poping Pages (Navigating Backward)

If you want to move back on previous page on some action you can use pop() using navigator as a prop.

backHandler = ()=>{
 this.props.navigator.pop();

}

START CODING :

App.js

import { Navigation } from "react-native-navigation";
import MainScreen from "./src/screens/MainScreen/MainScreen";
import MovieDetail from "./src/screens/MovieDetail/MovieDetail";
import Movies from "./src/screens/Movies/Movies";
import Plays from "./src/screens/Plays/Plays";
import Events from "./src/screens/Events/Events";

// Register Screens
Navigation.registerComponent(
  "navigation-example.MainScreen",
  () => MainScreen);

  Navigation.registerComponent(
   "navigation-example.Movies",
   () => Movies);

  Navigation.registerComponent(
   "navigation-example.Plays",
   () => Plays);

  Navigation.registerComponent(
   "navigation-example.Events",
   () => Events);

  Navigation.registerComponent(
  "navigation-example.MovieDetail",
   () => MovieDetail);



// Starting App
Navigation.startSingleScreenApp({
  screen: {
    screen: "navigation-example.MainScreen",
    title: "Entertainment"
  }
});

 

MainScreen.js

import React, { Component } from "react";
import {View,Text,Button,StyleSheet} from "react-native";
import StartMainTabs from "../MainTabs/StartMainTabs";


class MainScreen extends Component{


nextHandler = ()=>{
StartMainTabs();

}
render(){

return(
<View style={styles.container}>
<Text style={styles.titleText} >Entertainment</Text>
<Button color="#841584" title="Next" onPress={this.nextHandler}/>
</View>
);
}

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: 'center',
    backgroundColor:"#521751"
  },
    titleText: {
       fontSize: 50,
       fontWeight: 'bold',
       color: "#fa923f"
     }
  });
export default MainScreen;

 

StartMainTabs.js

import { Navigation } from 'react-native-navigation';
import { Platform } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';

const startTabs = () => {
    Promise.all([
        Icon.getImageSource(Platform.OS === 'android' ? "md-videocam" : "ios-videocam", 30),
        Icon.getImageSource(Platform.OS === 'android' ? "md-musical-notes" : "ios-musical-notes", 30),
        Icon.getImageSource(Platform.OS === 'android' ? "md-easel" : "ios-easel", 30),

    ]).then(sources => {
        Navigation.startTabBasedApp({
            tabs: [
                {
                    screen: "navigation-example.Movies",
                    label: "Movies",
                    title: "Movies",
                    icon: sources[0],


                },
                {
                    screen: "navigation-example.Plays",
                    label: "Plays",
                    title: "Plays",
                    icon: sources[1],


                },
                {
                    screen: "navigation-example.Events",
                    label: "Events",
                    title: "Events",
                    icon: sources[2],
                                }
            ],
            tabsStyle: {
                tabBarSelectedButtonColor: "orange"
            },

            appStyle: {
                tabBarSelectedButtonColor: "orange"
            }

        });
    });
};

export default startTabs;

 

Movies.js

import React, { Component } from "react";
import {StyleSheet, FlatList} from "react-native";
import movieImageOne from "../../assets/black_panther.jpg";
import movieImageTwo from "../../assets/death_of_stalin.jpg";
import movieImageThree from "../../assets/the_rider.jpg";
import movieImageFour from "../../assets/zama.jpg";
import movieImageFive from "../../assets/annhilation.jpg";
import ListItem from "../../component/ListItem/ListItem";


class Movies extends Component{


onItemPressedHandler= (name,image)=>{

this.props.navigator.push({
      screen: "navigation-example.MovieDetail",
      title: name,
      passProps: {
        movieName: name,
        movieImage: image
      }
    });
}
render(){

return(
 <FlatList
      style={styles.listContainer}
       data={[
                  { movieName: 'Black Panther',
                  movieImage:  movieImageOne,
                  key: 'a'
                   },
                  { movieName: 'The Death of Stalin',
                  movieImage:  movieImageTwo,
                  key: 'b'
                   },
                   { movieName: 'The Rider',
                    movieImage:  movieImageThree,
                    key: 'c'
                    },
                   { movieName: 'Zama',
                     movieImage:  movieImageFour,
                     key: 'd'
                    },
                   { movieName: 'Annihilation',
                     movieImage:  movieImageFive,
                     key: 'e'
                    },
                ]}

      renderItem={(info) => (
        <ListItem
          movieName={info.item.movieName}
          movieImage={info.item.movieImage}
          onItemPressed={() => this.onItemPressedHandler(info.item.movieName,info.item.movieImage)}
        />
      )}
    />
);
}

}
const styles = StyleSheet.create({
  listContainer: {
    width: "100%"
  }
});

export default Movies;

 

Plays.js

import React, { Component } from "react";
import {View,Text,StyleSheet} from "react-native";


class Plays extends Component{

render(){

return(
<View style={styles.container}>
<Text style={styles.titleText}>Plays</Text>
</View>
);
}

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: 'center',
    backgroundColor:"#6a5acd"
  },
    titleText: {
       fontSize: 50,
       fontWeight: 'bold',
       color: "#fa923f"
     }
  });
export default Plays;

 

Events.js

import React, { Component } from "react";
import {View,Text,StyleSheet} from "react-native";


class Events extends Component{

render(){

return(
<View style={styles.container}>
<Text style={styles.titleText}>Events</Text>
</View>
);
}

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: 'center',
    backgroundColor:"#228b22"
  },
    titleText: {
       fontSize: 50,
       fontWeight: 'bold',
       color: "#fa923f"
     }
  });
export default Events;

 

MovieDetail.js

import React, { Component } from "react";
import {View,Text,StyleSheet,Image,Button} from "react-native";


class MovieDetail extends Component{


backHandler = ()=>{
 this.props.navigator.pop();

}

render(){

return(
<View style={styles.container}>
            <Image
              source={this.props.movieImage}
              style={styles.movieImage}
            />

              <Text style={styles.movieName}>
                        {this.props.movieName}
                      </Text>
                      <Button color="#841584" title="Back" onPress={this.backHandler}/>
                    </View>
          );
}

}

const styles = StyleSheet.create({
  container: {

    flex: 1,
    padding:50,


    alignItems: "center",
        justifyContent: 'center'
  },
    movieImage: {
       width: "100%",
       height: "100%"
     },
     movieName: {
       fontWeight: "bold",
       textAlign: "center",
       fontSize: 30,
       color: "#521751",

     }
  });
export default MovieDetail;

ListItem.js

import React from "react";
import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native";

const listItem = props => (
  <TouchableOpacity  onPress={props.onItemPressed}>
    <View style={styles.listItem}>
      <Image resizeMode="cover" source={props.movieImage} style={styles.movieImage} />
      <Text>{props.movieName}</Text>
    </View>
  </TouchableOpacity>
);

const styles = StyleSheet.create({
  listItem: {
    width: "100%",
    marginBottom: 5,
    padding: 10,
    backgroundColor: "#eee",
    flexDirection: "row",
    alignItems: "center"
  },
  movieImage: {
      marginRight: 8,
      height: 30,
      width: 30
  }
});

export default listItem;

Leave a Reply