Android Navigation Component Jetpack in Kotlin

This post shows you how to implement the jetpack android navigation component using kotlin programming language in your android app.

Android navigation component helps developers to anticipate navigation flow of application. Android navigation component consists of three key parts that are described below. You can also checkout sample app at HERE.

  • Navigation graph: An XML resource that contains all navigation-related information in one centralized location. This includes all of the individual content areas within your app, called destinations, as well as the possible paths that a user can take through your app.
  • NavHost: An empty container that displays destinations from your navigation graph. The Navigation component contains a default NavHost implementation, NavHostFragment, that displays fragment destinations.
  • NavController: An object that manages app navigation within a NavHost. The NavController orchestrates the swapping of destination content in the NavHost as users move throughout your app.

 

 

 

Add the below dependencies in your app level build.gradle

apply plugin: 'kotlin-kapt'
apply plugin: 'androidx.navigation.safeargs.kotlin'

android {
    dataBinding{
        enabled true
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
    }
}

dependencies {
    implementation 'androidx.navigation:navigation-fragment-ktx:2.2.1'
    implementation 'androidx.navigation:navigation-ui-ktx:2.2.1'
    implementation 'com.android.support:recyclerview-v7:28.1.1'
    implementation 'com.android.support:cardview-v7:28.1.1'
}
 
 

Add the below dependency in your top level build.gradle

 dependencies {
        classpath 'com.android.tools.build:gradle:3.6.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath  'android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0'
    }
 
 

Create a navigation graph for android navigation component

 
To add a navigation graph to your project, do the following:
 
1. In the Project window, right-click on the res directory and select New > Android Resource File. The New Resource File dialog appears.
2. Type a name in the File name field, such as “nav_graph”.
3. Select Navigation from the Resource type drop-down list, and then click OK.

 

Add a NavHost to an activity

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".activities.MainActivity">

        <fragment
            android:id="@+id/nav_host_fragment"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:name="androidx.navigation.fragment.NavHostFragment"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
 
 

Add destinations to the navigation graph

 
To add a new destination using the Navigation Editor, do the following:
 
1. In the Navigation Editor, click the New Destination icon , and then click Create new destination.
2. In the New Android Component dialog that appears, create your fragment.
 
Output will be
 
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/employeesListFragment">

    <fragment
        android:id="@+id/employeesListFragment"
        android:name="com.example.navigationjetpacksample.fragments.EmployeesListFragment"
        android:label="EmployeesListFragment"
        tools:layout="@layout/frag_employees_list"/>
    
</navigation>
 
 

Connect destinations for android navigation component

 
You can use the Navigation Editor to connect two destinations by doing the following:
1. In the Design tab, hover over the right side of the destination that you want users to navigate from. A circle appears over the right side of the destination
2. Click and drag your cursor over the destination you want users to navigate to, and release. The resulting line between the two destinations represents an action
 
Output will be
 
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/employeesListFragment">

    <fragment
        android:id="@+id/employeesListFragment"
        android:name="com.example.navigationjetpacksample.fragments.EmployeesListFragment"
        android:label="EmployeesListFragment"
        tools:layout="@layout/frag_employees_list">
        <action
            android:id="@+id/action_employeesListFragment_to_employeeDetailsFragment"
            app:destination="@id/employeeDetailsFragment" />
        <action
            android:id="@+id/action_employeesListFragment_to_addEmployeeFragment"
            app:destination="@id/addEmployeeFragment" />
        <action
            android:id="@+id/action_employeesListFragment_to_editEmployeeFragment"
            app:destination="@id/editEmployeeFragment" />
        <action
            android:id="@+id/action_employeesListFragment_to_deleteEmployeeFragment"
            app:destination="@id/deleteEmployeeFragment" />
    </fragment>

</navigation>
 
 

Navigate to a destination

 
Kotlin:
  • Fragment.findNavController()
  • View.findNavController()
  • Activity.findNavController(viewId: Int)
 
Java:
  • NavHostFragment.findNavController(Fragment)
  • Navigation.findNavController(Activity, @IdRes int viewId)
  • Navigation.findNavController(View)
 
fab_add.setOnClickListener {           it.findNavController().navigate(EmployeesListFragmentDirections.actionEmployeesListFragmentToAddEmployeeFragment())
}
 
 

Pass data between destinations with Safe Args

To pass data between destinations, first define the argument by adding it to the destination that receives it by following these steps:
 
1. In the Navigation editor, click on the destination that receives the argument.
2. In the Attributes panel, click Add (+).
3. In the Add Argument Link window that appears, enter the argument name, argument type, whether the argument is nullable, and a default value, if needed.
4. Click Add. Notice that the argument now appears in the Arguments list in the Attributes panel.
 
Output will be
 
<fragment
    android:id="@+id/employeeDetailsFragment"
    android:name="com.example.navigationjetpacksample.fragments.EmployeeDetailsFragment"
    android:label="EmployeeDetailsFragment"
    tools:layout="@layout/frag_employee_details">
    <argument
        android:name="employee"
        app:argType="com.example.navigationjetpacksample.models.Employee" />
</fragment>
 
 

For optional arguments

<fragment
    android:id="@+id/employeeDetailsFragment"
    android:name="com.example.navigationjetpacksample.fragments.EmployeeDetailsFragment"
    android:label="EmployeeDetailsFragment"
    tools:layout="@layout/frag_employee_details">
    <argument
        android:name="employee"
        app:argType="com.example.navigationjetpacksample.models.Employee"
        android:defaultValue="@null"
        app:nullable="true"/>
</fragment>

package com.example.navigationjetpacksample.models

import java.io.Serializable

data class Employee(val id: Int, val firstName: String, val lastName: String, val email: String, val phoneNo:String, val age:String, val salary:String) : Serializable

 
 

In your sending destination’s code

holder.itemBinding.root.setOnClickListener {
            val action = EmployeesListFragmentDirections.actionEmployeesListFragmentToEmployeeDetailsFragment(getEmployee)
            it.findNavController().navigate(action)
}
 
 

In your receiving destination’s code

val args : EmployeeDetailsFragmentArgs by navArgs()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding : FragEmployeeDetailsBinding = DataBindingUtil.inflate(inflater,
            R.layout.frag_employee_details,container,false)
        binding.employee = args.employee
        return binding.root
    }
 
 

Animate transitions between destinations

 
 To add animations to an action, do the following:
 
1. In the Navigation editor, click on the action where the animation should occur.
2. In the Animations section of the Attributes panel, click the dropdown arrow next to the animation you’d like to add. You can choose between the following types:
Entering a destination
Exiting a destination
Entering a destination via a pop action
Exiting a destination via a pop action
3. Choose an animation from the list of project animations that appears.
 
Output will be
 
<fragment
    android:id="@+id/employeesListFragment"
    android:name="com.example.navigationjetpacksample.fragments.EmployeesListFragment"
    android:label="EmployeesListFragment"
    tools:layout="@layout/frag_employees_list">
    <action
        android:id="@+id/action_employeesListFragment_to_employeeDetailsFragment"
        app:destination="@id/employeeDetailsFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left"
        app:popEnterAnim="@anim/enter_from_left"
        app:popExitAnim="@anim/exit_to_right"/>
</fragment>
 
 

Create Fragments, Adapter and Activity for UI

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_employees"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:paddingTop="15dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="16dp"
            android:src="@android:drawable/ic_input_add"
            />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>
package com.example.navigationjetpacksample.fragments

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.navigationjetpacksample.R
import com.example.navigationjetpacksample.adapters.EmployeesListAdapter
import com.example.navigationjetpacksample.databinding.FragEmployeesListBinding
import com.example.navigationjetpacksample.models.Employee
import com.example.navigationjetpacksample.utils.Constants.listEmployees
import kotlinx.android.synthetic.main.frag_employees_list.*

class EmployeesListFragment : Fragment() {

    private val args : EmployeesListFragmentArgs by navArgs()
    private var ctx: Context? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        this.ctx = context
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding: FragEmployeesListBinding = DataBindingUtil.inflate(
            inflater,
            R.layout.frag_employees_list, container, false
        )

        args.employee?.let {mEmployee ->
            if (args.previousScreen == AddEmployeeFragment::class.java.name) {
                listEmployees.add(mEmployee)
            } else {
                var pos = -1
                listEmployees.forEach {
                    pos++
                    if (it.id == mEmployee.id) {
                        listEmployees[pos] = mEmployee
                    }
                }
            }
        }

        binding.recyclerEmployees.layoutManager = LinearLayoutManager(ctx)
        val adapter = ctx?.let { EmployeesListAdapter(it,listEmployees) }
        binding.recyclerEmployees.adapter = adapter

        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        fab_add.setOnClickListener {
            it.findNavController().navigate(EmployeesListFragmentDirections.actionEmployeesListFragmentToAddEmployeeFragment())
        }

    }

    override fun onDetach() {
        super.onDetach()
        this.ctx = null
    }

}

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="employee"
            type="com.example.navigationjetpacksample.models.Employee" />
    </data>

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        app:cardCornerRadius="10dp">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="15dp">

            <TextView
                android:id="@+id/txt_employee_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{employee.firstName + ` `+ employee.lastName}"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                android:textSize="25sp"
                android:textStyle="bold"/>

            <ImageView
                android:id="@+id/img_delete"
                android:layout_width="20dp"
                android:layout_height="20dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                android:src="@android:drawable/ic_menu_delete" />

            <ImageView
                android:id="@+id/img_edit"
                android:layout_width="20dp"
                android:layout_height="20dp"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/img_delete"
                android:layout_marginEnd="15dp"
                android:src="@android:drawable/ic_menu_edit"/>

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.cardview.widget.CardView>

</layout>
package com.example.navigationjetpacksample.adapters

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import com.example.navigationjetpacksample.R
import com.example.navigationjetpacksample.databinding.FragEmployeesListRowBinding
import com.example.navigationjetpacksample.fragments.EmployeesListFragmentDirections
import com.example.navigationjetpacksample.models.Employee

class EmployeesListAdapter (private val context: Context, private val list: MutableList<Employee>) : RecyclerView.Adapter<EmployeesListAdapter.MyViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val inflater = LayoutInflater.from(context)
        val binding: FragEmployeesListRowBinding = DataBindingUtil.inflate(inflater, R.layout.frag_employees_list_row,parent,false)
        return MyViewHolder(binding)
    }

    override fun getItemCount(): Int {
        return list.size
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val getEmployee = list[position]
        holder.itemBinding.employee = getEmployee

        holder.itemBinding.root.setOnClickListener {
            val action = EmployeesListFragmentDirections.actionEmployeesListFragmentToEmployeeDetailsFragment(getEmployee)
            it.findNavController().navigate(action)
        }

        holder.itemBinding.imgEdit.setOnClickListener {
            val action = EmployeesListFragmentDirections.actionEmployeesListFragmentToEditEmployeeFragment(getEmployee)
            it.findNavController().navigate(action)
        }

        holder.itemBinding.imgDelete.setOnClickListener {
            val action = EmployeesListFragmentDirections.actionEmployeesListFragmentToDeleteEmployeeFragment(getEmployee)
            it.findNavController().navigate(action)
        }

    }

    class MyViewHolder(val itemBinding: FragEmployeesListRowBinding) : RecyclerView.ViewHolder(itemBinding.root){

        private var binding : FragEmployeesListRowBinding? = null

        init {
            this.binding = itemBinding
        }

    }

}

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <EditText
            android:id="@+id/edt_first_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="25dp"
            android:layout_marginTop="25dp"
            android:layout_marginEnd="25dp"
            android:hint="Please enter first name"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <EditText
            android:id="@+id/edt_last_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter last name"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_first_name" />

        <EditText
            android:id="@+id/edt_email"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter email"
            android:inputType="textEmailAddress"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_last_name" />

        <EditText
            android:id="@+id/edt_phone_no"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter phone no"
            android:inputType="phone"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_email" />

        <EditText
            android:id="@+id/edt_age"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter age"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_phone_no"
            android:inputType="number"/>

        <EditText
            android:id="@+id/edt_salary"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter salary"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_age"
            android:inputType="number"/>

        <Button
            android:id="@+id/btn_add"
            android:layout_width="100dp"
            android:layout_height="50dp"
            android:layout_marginTop="50dp"
            android:text="Submit"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edt_salary" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

package com.example.navigationjetpacksample.fragments

import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs
import com.example.navigationjetpacksample.R
import com.example.navigationjetpacksample.databinding.FragAddEmployeeBinding
import com.example.navigationjetpacksample.models.Employee
import kotlinx.android.synthetic.main.frag_add_employee.*
import kotlinx.android.synthetic.main.frag_edit_employee.*
import kotlinx.android.synthetic.main.frag_edit_employee.edt_age
import kotlinx.android.synthetic.main.frag_edit_employee.edt_email
import kotlinx.android.synthetic.main.frag_edit_employee.edt_first_name
import kotlinx.android.synthetic.main.frag_edit_employee.edt_last_name
import kotlinx.android.synthetic.main.frag_edit_employee.edt_phone_no
import kotlinx.android.synthetic.main.frag_edit_employee.edt_salary
import kotlin.random.Random

class AddEmployeeFragment : Fragment() {

    private var ctx: Context? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        this.ctx = context
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding : FragAddEmployeeBinding = DataBindingUtil.inflate(inflater,R.layout.frag_add_employee,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        btn_add.setOnClickListener {
            val firstName = edt_first_name.text.toString()
            val lastName = edt_last_name.text.toString()
            val email = edt_email.text.toString()
            val phoneNo = edt_phone_no.text.toString()
            val age = edt_age.text.toString()
            val salary = edt_salary.text.toString()

            if(!TextUtils.isEmpty(firstName) &amp;&amp; !TextUtils.isEmpty(lastName) &amp;&amp; !TextUtils.isEmpty(email) &amp;&amp; !TextUtils.isEmpty(phoneNo) &amp;&amp; !TextUtils.isEmpty(age) &amp;&amp; !TextUtils.isEmpty(salary)){
                val randomNo = Random.nextInt(97) + 4;
                val newEmployee = Employee(randomNo,firstName,lastName,email,phoneNo,age,salary)
                val action = AddEmployeeFragmentDirections.actionAddEmployeeFragmentToEmployeesListFragment(newEmployee,AddEmployeeFragment::class.java.name)
                it.findNavController().navigate(action)
            } else{
                Toast.makeText(ctx,"All fields are required", Toast.LENGTH_SHORT).show()
            }

        }
    }

    override fun onDetach() {
        super.onDetach()
        this.ctx = null
    }

}

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
    <variable
        name="employee"
        type="com.example.navigationjetpacksample.models.Employee" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <EditText
            android:id="@+id/edt_first_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="25dp"
            android:layout_marginTop="25dp"
            android:layout_marginEnd="25dp"
            android:hint="Please enter first name"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:text="@{employee.firstName}"/>

        <EditText
            android:id="@+id/edt_last_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter last name"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_first_name"
            android:text="@{employee.lastName}"/>

        <EditText
            android:id="@+id/edt_email"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter email"
            android:inputType="textEmailAddress"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_last_name"
            android:text="@{employee.email}"/>

        <EditText
            android:id="@+id/edt_phone_no"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter email"
            android:inputType="phone"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_email"
            android:text="@{employee.phoneNo}"/>

        <EditText
            android:id="@+id/edt_age"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter age"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_phone_no"
            android:inputType="number"
            android:text="@{employee.age}"/>

        <EditText
            android:id="@+id/edt_salary"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:hint="Please enter salary"
            app:layout_constraintEnd_toEndOf="@+id/edt_first_name"
            app:layout_constraintStart_toStartOf="@+id/edt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/edt_age"
            android:inputType="number"
            android:text="@{employee.salary}"/>

        <Button
            android:id="@+id/btn_edit"
            android:layout_width="100dp"
            android:layout_height="50dp"
            android:layout_marginTop="50dp"
            android:text="Submit"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edt_salary" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

package com.example.navigationjetpacksample.fragments

import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs
import com.example.navigationjetpacksample.R
import com.example.navigationjetpacksample.databinding.FragEditEmployeeBinding
import com.example.navigationjetpacksample.models.Employee
import kotlinx.android.synthetic.main.frag_edit_employee.*

class EditEmployeeFragment : Fragment() {

    private val args: EditEmployeeFragmentArgs by navArgs()

    private var ctx: Context? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        this.ctx = context
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding : FragEditEmployeeBinding = DataBindingUtil.inflate(inflater,
            R.layout.frag_edit_employee,container,false)
        binding.employee = args.employee
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        btn_edit.setOnClickListener {
            val firstName = edt_first_name.text.toString()
            val lastName = edt_last_name.text.toString()
            val email = edt_email.text.toString()
            val phoneNo = edt_phone_no.text.toString()
            val age = edt_age.text.toString()
            val salary = edt_salary.text.toString()

            if(!TextUtils.isEmpty(firstName) &amp;&amp; !TextUtils.isEmpty(lastName) &amp;&amp; !TextUtils.isEmpty(email) &amp;&amp; !TextUtils.isEmpty(phoneNo) &amp;&amp; !TextUtils.isEmpty(age) &amp;&amp; !TextUtils.isEmpty(salary)){
                val newEmployee = Employee(args.employee.id,firstName,lastName,email,phoneNo,age,salary)
                val action = EditEmployeeFragmentDirections.actionEditEmployeeFragmentToEmployeesListFragment(newEmployee,EditEmployeeFragment::class.java.name)
                it.findNavController().navigate(action)
            } else{
                Toast.makeText(ctx,"All fields are required",Toast.LENGTH_SHORT).show()
            }

        }
    }

    override fun onDetach() {
        super.onDetach()
        this.ctx = null
    }

}

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:text="Are you sure want to delete this employee?"
            app:layout_constraintVertical_bias="0.35"
            android:textSize="25sp"
            android:textStyle="bold"
            android:gravity="center"/>

        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cancel"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/btn_submit"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:textAllCaps="false"
            app:layout_constraintVertical_bias="0.55"/>

        <Button
            android:id="@+id/btn_submit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Submit"
            app:layout_constraintStart_toEndOf="@+id/btn_cancel"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:textAllCaps="false"
            app:layout_constraintVertical_bias="0.55"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

package com.example.navigationjetpacksample.fragments

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs
import com.example.navigationjetpacksample.R
import com.example.navigationjetpacksample.databinding.FragDeleteEmployeeBinding
import com.example.navigationjetpacksample.utils.Constants
import kotlinx.android.synthetic.main.frag_delete_employee.*

class DeleteEmployeeFragment : Fragment() {

    private val args : DeleteEmployeeFragmentArgs by navArgs()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding : FragDeleteEmployeeBinding = DataBindingUtil.inflate(inflater,
            R.layout.frag_delete_employee,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        btn_cancel.setOnClickListener {
            it.findNavController().popBackStack()
        }

        btn_submit.setOnClickListener {
            Constants.listEmployees.remove(args.employee)
            it.findNavController().navigate(DeleteEmployeeFragmentDirections.actionDeleteEmployeeFragmentToEmployeesListFragment2())
        }

    }

}

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
    <variable
        name="employee"
        type="com.example.navigationjetpacksample.models.Employee" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/txt_first_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="25dp"
            android:layout_marginTop="25dp"
            android:layout_marginEnd="25dp"
            android:text="@{`First Name: ` + employee.firstName}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/txt_last_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="@{`Last Name: ` + employee.lastName}"
            app:layout_constraintEnd_toEndOf="@+id/txt_first_name"
            app:layout_constraintStart_toStartOf="@+id/txt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/txt_first_name" />

        <TextView
            android:id="@+id/txt_email"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="@{`Email: ` + employee.email}"
            app:layout_constraintEnd_toEndOf="@+id/txt_first_name"
            app:layout_constraintStart_toStartOf="@+id/txt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/txt_last_name" />

        <TextView
            android:id="@+id/txt_phone_no"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="@{`Phone No: ` + employee.phoneNo}"
            app:layout_constraintEnd_toEndOf="@+id/txt_first_name"
            app:layout_constraintStart_toStartOf="@+id/txt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/txt_email" />

        <TextView
            android:id="@+id/txt_age"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            app:layout_constraintEnd_toEndOf="@+id/txt_first_name"
            app:layout_constraintStart_toStartOf="@+id/txt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/txt_phone_no"
            android:text="@{`Age: ` + employee.age}"/>

        <TextView
            android:id="@+id/txt_salary"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="@{`Salary: ` + employee.salary}"
            app:layout_constraintEnd_toEndOf="@+id/txt_first_name"
            app:layout_constraintStart_toStartOf="@+id/txt_first_name"
            app:layout_constraintTop_toBottomOf="@+id/txt_age" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

package com.example.navigationjetpacksample.fragments

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import com.example.navigationjetpacksample.R
import com.example.navigationjetpacksample.databinding.FragEmployeeDetailsBinding

class EmployeeDetailsFragment : Fragment() {

    private val args : EmployeeDetailsFragmentArgs by navArgs()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding : FragEmployeeDetailsBinding = DataBindingUtil.inflate(inflater,
            R.layout.frag_employee_details,container,false)
        binding.employee = args.employee
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }

}

package com.example.navigationjetpacksample.activities

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.navigationjetpacksample.R
import com.example.navigationjetpacksample.databinding.ActivityMainBinding
import com.example.navigationjetpacksample.models.Employee
import com.example.navigationjetpacksample.utils.Constants.listEmployees

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding: ActivityMainBinding = DataBindingUtil.setContentView(this@MainActivity, R.layout.activity_main)

        listEmployees = mutableListOf()
        listEmployees.add(Employee(1,"Roberto","Sanchez","rob@san.com","423424244","37","324324"))
        listEmployees.add(Employee(2,"Luis","Hernandez","lui@her.com","368562411","32","789218"))
        listEmployees.add(Employee(3,"David","Robertson","dav@rob.com","640234284","35","565787"))

    }
}

 

 

Final Navigation Graph

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/employeesListFragment">

<fragment
    android:id="@+id/employeesListFragment"
    android:name="com.example.navigationjetpacksample.fragments.EmployeesListFragment"
    android:label="EmployeesListFragment"
    tools:layout="@layout/frag_employees_list">
    <action
        android:id="@+id/action_employeesListFragment_to_employeeDetailsFragment"
        app:destination="@id/employeeDetailsFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left"
        app:popEnterAnim="@anim/enter_from_left"
        app:popExitAnim="@anim/exit_to_right"/>
    <action
        android:id="@+id/action_employeesListFragment_to_editEmployeeFragment"
        app:destination="@id/editEmployeeFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left"
        app:popEnterAnim="@anim/enter_from_left"
        app:popExitAnim="@anim/exit_to_right"/>
    <action
        android:id="@+id/action_employeesListFragment_to_deleteEmployeeFragment"
        app:destination="@id/deleteEmployeeFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left"
        app:popEnterAnim="@anim/enter_from_left"
        app:popExitAnim="@anim/exit_to_right"/>
    <action
        android:id="@+id/action_employeesListFragment_to_addEmployeeFragment"
        app:destination="@id/addEmployeeFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left"
        app:popEnterAnim="@anim/enter_from_left"
        app:popExitAnim="@anim/exit_to_right"/>
    <argument
        android:name="employee"
        app:argType="com.example.navigationjetpacksample.models.Employee"
        android:defaultValue="@null"
        app:nullable="true"/>
    <argument
        android:name="previousScreen"
        app:argType="string"
        android:defaultValue="@null"
        app:nullable="true"/>
</fragment>

<fragment
    android:id="@+id/addEmployeeFragment"
    android:name="com.example.navigationjetpacksample.fragments.AddEmployeeFragment"
    android:label="AddEmployeeFragment"
    tools:layout="@layout/frag_add_employee">
    <action
        android:id="@+id/action_addEmployeeFragment_to_employeesListFragment"
        app:destination="@id/employeesListFragment"
        app:popUpTo="@id/employeesListFragment"
        app:popUpToInclusive="true"
        app:launchSingleTop="true" />
</fragment>

<fragment
    android:id="@+id/employeeDetailsFragment"
    android:name="com.example.navigationjetpacksample.fragments.EmployeeDetailsFragment"
    android:label="EmployeeDetailsFragment"
    tools:layout="@layout/frag_employee_details">
    <argument
        android:name="employee"
        app:argType="com.example.navigationjetpacksample.models.Employee" />
</fragment>

<fragment
    android:id="@+id/editEmployeeFragment"
    android:name="com.example.navigationjetpacksample.fragments.EditEmployeeFragment"
    android:label="EditEmployeeFragment"
    tools:layout="@layout/frag_edit_employee">
    <argument
        android:name="employee"
        app:argType="com.example.navigationjetpacksample.models.Employee" />
    <action
        android:id="@+id/action_editEmployeeFragment_to_employeesListFragment"
        app:destination="@id/employeesListFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left"
        app:launchSingleTop="true"
        app:popUpTo="@id/employeesListFragment"
        app:popUpToInclusive="true" />
</fragment>

<fragment
    android:id="@+id/deleteEmployeeFragment"
    android:name="com.example.navigationjetpacksample.fragments.DeleteEmployeeFragment"
    android:label="DeleteEmployeeFragment"
    tools:layout="@layout/frag_delete_employee">
    <action
        android:id="@+id/action_deleteEmployeeFragment_to_employeesListFragment2"
        app:destination="@id/employeesListFragment"
        app:popUpTo="@id/employeesListFragment"
        app:popUpToInclusive="true"
        app:launchSingleTop="true" />
    <argument
        android:name="employee"
        app:argType="com.example.navigationjetpacksample.models.Employee" />
</fragment>
</navigation>
 
 
android navigation component
 
 
navigation component android
 
 
android jetpack
 
 
android navigation component
 
 
navigation component
 
 

4 thoughts on “Android Navigation Component Jetpack in Kotlin

Leave a Reply