How To Add Native Screens With Navigation to Your React Native Application (Android)

How To Add Native Screens With Navigation to Your React Native Application (Android)

This text is about including an area display screen to a React Native utility. On this tutorial, we’ll use Kotlin so as to add native navigation and screens to React Native apps.

We will transfer between the React Native and native screens. Including native screens to an app is helpful after we want one other safety layer, for instance, if we want to add a fee display screen. One other factor it does is offload the JavaScript thread.

 

 

For the aim of this tutorial, I’ve created a easy React Native (RN) app that shows some native and a few RN screens. We’ll create two RN screens and three native screens. We’ll create the native screens as a React Native Module.

 

Preliminary setup

One of the simplest ways to create a React Native module is to make use of bob. Bob is an easy CLI to scaffold and construct React Native libraries.

To create the module simply use the npm command.
npx @react-native-community/bob create react-native-awesome-module

Bob will ask you some questions concerning the package deal identify, description, writer, and so forth.

A very powerful query is, “What sort of package deal do you need to develop?” Please select “Native module in Kotlin and Swift”.

Bob will generate all of the wanted information and an instance listing with React Native Utility. We’ll use an instance listing to check our module.

Let’s open the instance listing, and set up React Navigation utilizing the instructions under.

npm set up @react-navigation/native

npm set up react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

npm set up @react-navigation/stack

 

Create a “navigation” listing, inside it create “RootNavigation.tsx”. On this step, we’ll add two screens into React Native.

import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Most important from '../screens/Most important';
import 'react-native-gesture-handler';
import One other from '../screens/One other';

const RootNavigation = () => {
 const Stack = createStackNavigator();

 return (
   <NavigationContainer>
     <Stack.Navigator>
       <Stack.Display identify="Residence" part=Most important />
       <Stack.Display identify="One other" part=One other />
     </Stack.Navigator>
   </NavigationContainer>
 );
};
export default RootNavigation;

 

Then add the code under to “App.js”.

import RootNavigation from './navigation/RootNavigation';

export default perform App() {
 return <RootNavigation />;
}

 

Create a “screens” listing, then inside it create “Most important.tsx” and “One other.tsx“.

import React from 'react';
import  View, Textual content  from 'react-native';

const One other = () => ;

export default One other;

 

In “Most important.tsx”, we’re utilizing “ModuleName.showView()” to show “native screens stack”.

import React from 'react';
import { View, Button } from 'react-native';
import ModuleName from 'module-name';

const Most important = ({ navigation }) => {
 return (
   <View type=>
     <Button
       onPress=
       title=
     />
     <View type= />
     <Button
       onPress={() => ModuleName.showView()}
       title={'Open Native Screens'}
     />
     <View type= />
     <Button
       onPress={() => ModuleName.showViewNavigateTo(second)}
       title='Open Native One other Display'
     />
   </View>
 );
};


export default Most important;

 

Now it’s time so as to add “showView” and “showViewNavigateTo” to our module.

Open “index.tsx” within the module root listing and add it. It is going to expose the native strategies and we can name them in React Native.

sort ModuleNameType = 
 showView(): Promise<void>;
 showViewNavigateTo(textual content?: string): Promise<void>;
;

Native Screens Implementation (Android)

On this step, we now have so as to add navigation to the native a part of the app. Then we’ll add some native screens and we’ll connect native navigation to the React Native exercise. After these steps, we can show the native screens stack.

For the steps under please use Android Studio.

Initially, open the “android” listing positioned within the module’s root listing.

Add the code under to “android/src/most important/java/com/moduleName/ModuleNameModule.kt”.

As a result of React Native bridge doesn’t help methodology overloading, we’re creating two strategies:

  • showView” will show the foundation stack of our native navigation.
  • showViewNavigateTo” — utilizing this methodology you possibly can navigate to a selected native display screen.

Utilizing

val intent = Intent(reactApplicationContext, ModuleNameActivity::class.java)

we connect our exercise to the React Native course of.

@ReactMethod
enjoyable showView(promise: Promise) {
 val intent = Intent(reactApplicationContext, ModuleNameActivity::class.java)
 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
 reactApplicationContext.startActivity(intent)
 promise.resolve(true)
}

@ReactMethod
enjoyable showViewNavigateTo(textual content: String? = "", promise: Promise) 

Navigation setup

To create a local stack, we now have to put in a local navigation part package deal. Let’s add the code under to “android/construct.gradle”.

We have to add android navigation to dependencies on the backside of the file.

dependencies

After navigation dependencies are added we should always create “nav_graph”. So as to add a navigation graph to your mission, do the next:

  1. Create a “res” listing in “root/android/src/most important/”.
  2. Within the Undertaking window, right-click on the res listing and choose New > Android Useful resource File. The New Useful resource File dialog seems.
  3. Kind a reputation within the File identify area, corresponding to “nav_graph”.
  4. Choose Navigation from the Useful resource sort drop-down checklist, after which click on OK.

 

Then create “view_layout.xml” in “res/format” and paste the code under. On this step, we’re embedding navigation to view with a header.
NavHostFragment supplies an space inside your format for self-contained navigation to happen.

<?xml model="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent">

 <com.google.android.materials.appbar.AppBarLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

   <androidx.appcompat.widget.Toolbar
     android:id="@+id/toolbar"
     android:layout_width="match_parent"
     android:layout_height="?attr/actionBarSize"
     android:background="?attr/colorPrimary" />

 </com.google.android.materials.appbar.AppBarLayout>

 <fragment
   android:id="@+id/fragment_nav"
   android:identify="androidx.navigation.fragment.NavHostFragment"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:defaultNavHost="true"
   app:navGraph="@navigation/nav_graph" />
</FrameLayout>

After we are carried out with the navigation graph we’re capable of create our navigation exercise. To do it, in “src/most important/java/com.yourpackagename/” create a file named “ModuleNameActivity.kt” or use your individual identify and fill it with the code under. Utilizing the worth handed to intent “val screenId = intent.getStringExtra(“screenId”)”, we’re capable of navigate to a selected native display screen from the React Native aspect.

package deal com.reactnativeawesomemodulern //<--Change to your package deal identify

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.ui.setupActionBarWithNavController

class ModuleNameActivity : AppCompatActivity() { // If you're utilizing customized identify change it right here

 lateinit var nav: NavController
 override enjoyable onSupportNavigateUp(): Boolean = nav.navigateUp()
 override enjoyable onCreate(savedInstanceState: Bundle?) {
   tremendous.onCreate(savedInstanceState)

   setContentView(R.format.view_layout)
   setSupportActionBar(findViewById(R.id.toolbar))

   nav = Navigation.findNavController(this, R.id.fragment_nav)

   setupActionBarWithNavController(nav)

   val screenId = intent.getStringExtra("screenId")

   when (screenId) {
     "first" -> nav.navigate(R.id.firstFragment)
     "second" -> nav.navigate(R.id.secondFragment)
   }
 }


}

 

Then we now have to register it in “AndroidManifest.xml” and add the code under to your file. Keep in mind to alter the package deal identify and the module identify to your individual.

...
<utility>
<exercise android:identify="com.packageName.ModuleNameActivity" /><!--  Change package deal identify and Module identify to your individual  -->


</utility>
 ...
</manifest>

 

Lastly , we will create native screens. To take action, open the beforehand created “nav_graph”. Within the opened file:

  1. Press add ( + icon).
  2. Create a brand new vacation spot.

 

Within the pop up choose Fragment (Clean) then press Subsequent. Within the fragment identify sort “MainAppFragment”. Choose Kotlin in Supply Language and press End. It provides two information to your mission:

  • An xml format file.
  • The display screen controller file.

Open the xml format file in textual content editor mode and paste within the code under. It is going to create a format with two buttons.

<?xml model="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="heart"
 android:orientation="vertical">

 <Button
   android:id="@+id/next_screen_button"
   type="@type/Widget.AppCompat.Button.Borderless.Coloured"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginBottom="10dp"
   android:textual content="Go to subsequent Display" />

 <Button
   android:id="@+id/another_screen_button"
   type="@type/Widget.AppCompat.Button.Borderless.Coloured"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:textual content="Go to a different Display" />
</LinearLayout>

 

Then open “MainAppFragment.kt” and paste the code introduced under. Keep in mind to interchange the package deal identify with your individual. On this step we’re making a controller for our most important native navigation display screen. On the display screen we now have two buttons with bounded actions. On-press strategies are related to buttons by organising an onClickListener to every component.

package deal com.reactnativeawesomemodulern // <- Keep in mind to interchange package deal identify with your individual

import android.os.Bundle
import android.view.View

import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController

class MainAppFragment : Fragment(R.format.fragment_main_app) {

 override enjoyable onViewCreated(view: View, savedInstanceState: Bundle?) {
   tremendous.onViewCreated(view, savedInstanceState)
   val firstButton: Button = view.findViewById<Button>(R.id.next_screen_button)

   val secondButton: Button = view.findViewById<Button>(R.id.another_screen_button)

   firstButton.setOnClickListener {
     this.onButtonPress()
   }
   secondButton.setOnClickListener {
     this.onSecondButtonPress()
   }
 }

 non-public enjoyable onButtonPress() {
   findNavController().navigate(R.id.firstFragment)
 }

 non-public enjoyable onSecondButtonPress() {
   findNavController().navigate(R.id.secondFragment)
 }

}

 

Create one other two screens (FirstFragment, SecondFragment) as defined above and substitute their content material with the code under.

FirstFragment
Format File

<?xml model="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="heart"
 android:orientation="vertical">

 <TextView
   android:id="@+id/textView"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:textual content="First Display"
  />

</LinearLayout>

Kotlin file “onCreateView” methodology

package deal com.reactnativeawesomemodulern // <- Keep in mind to interchange package deal identify with your individual

import androidx.fragment.app.Fragment

class FirstFragment : Fragment(R.format.fragment_first) {}

 

SecondFragment, on this display screen we’re permitting the consumer to shut the native stack by urgent the shut button. Utilizing “exercise?.end();”, we’re exiting the native display screen that’s being displayed above our React Native screens.

Format File

<?xml model="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="heart"
 android:orientation="vertical">

 <TextView
   android:id="@+id/textView"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:textual content="Second Display" />

 <Button
   android:id="@+id/close_button"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:textual content="Shut" />
</LinearLayout>

Kotlin file

package deal com.reactnativeawesomemodulern

import android.os.Bundle
import android.view.View
import android.widget.Button
import androidx.fragment.app.Fragment

class SecondFragment : Fragment(R.format.fragment_second) {

 override enjoyable onViewCreated(view: View, savedInstanceState: Bundle?) {
   tremendous.onViewCreated(view, savedInstanceState)

   val closeButton: Button = view.findViewById<Button>(R.id.close_button)

   closeButton.setOnClickListener {
     this.onCloseButtonPress()
   }
 }

 non-public enjoyable onCloseButtonPress() 

}

 

To vary display screen titles on the navigation bar, open “nav_graph.xml” in editor mode.

 

And substitute each android:label=”Display Title” with the required display screen identify.

And we’re carried out! Open the instance app and it is possible for you to to navigate between native and RN screens.

Because of utilizing react-native-bob we’re ready to make use of our native screens as a React Native module. The one factor we now have to do is to name “npm pack” on the root of the module folder.

Then we transfer the file generated to the mission and add “react-native-awesome-module-rn”: “file:react-native-awesome-module-rn-0.1.0.tgz” to the dependencies in package deal.json.

Now you possibly can import and use these screens as a module!
Instance code out there right here.

Conclusion

Utilizing native screens in React Native may be helpful after we require a further layer of safety or if we want to current a display screen that’s exhausting to realize or not optimum when created with React Native. This tutorial reveals the actual potential of React Native, the place we’re ready so as to add a local answer to any growth step of an current utility created with React Native.