Navigation Drawer (with Navigation component?)

Add dependency:

dependencies {
    ...
    implementation "com.google.android.material:material:$version_supportlib" // Add version number to build.gradle also
}

Make sure any Fragments you wish to navigate to have been added to the Navigation Design window.

Create a new menu (e.g. navdrawer_menu.xml) in the res/menu folder.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> // All of this can be done through the GUI also

    <item
        android:id="@+id/firstFragment"
        android:icon="@drawable/first"
        android:title="@string/first" />
    <item
        android:id="@+id/secondFragment"
        android:icon="@drawable/second"
        android:title="@string/second" />
</menu>

In your main Activity layout file:

<?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">
    
    <androidx.drawerlayout.widget.DrawerLayout // Wrap the main ViewGroup in the DrawerLayout tag and give it an id
        android:id="@+id/drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <fragment
                android:id="@+id/myNavHostFragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:defaultNavHost="true"
                app:navGraph="@navigation/navigation" />
        </LinearLayout>
        
        <com.google.android.material.navigation.NavigationView // Create the NavDrawer element and give it an id
            android:id="@+id/navView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start" // Aligns it to the left of the screen for LtR languages
            app:headerLayout="@layout/nav_header" // Point to a layout file to define a custom header for your menu
            app:menu="@menu/navdrawer_menu" /> // Point it at the menu resource we just created

    </androidx.drawerlayout.widget.DrawerLayout>

</layout>

And in the main Activity file:

import ...

class MainActivity : AppCompatActivity() {
    lateinit var drawerLayout: DrawerLayout
    lateinit var navController: NavController
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        @Suppress("UNUSED_VARIABLE")
        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        navController = this.findNavController(R.id.myNavHostFragment)
        drawerLayout = binding.drawerLayout // Get the DrawerLayout
        NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout) // Add the DrawerLayout to the ActionBar
        NavigationUI.setupWithNavController(binding.navView, navController) // Link the navigation view with the UI
    }

    override fun onSupportNavigateUp(): Boolean {
//        return navController.navigateUp() // Get rid of this return statement
        return NavigationUI.navigateUp(navController, drawerLayout) // Use this instead which includes the DrawerLayout
    }
}

Add overflow menu with Navigation component in Kotlin

Create a menu resource file in the res/menu folder:

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

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/aboutFragment"
        android:title="@string/about" />

</menu>

In the relevant Activity/Fragment:

import ...

class TitleFragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val binding: FragmentTitleBinding = DataBindingUtil.inflate(
                inflater, R.layout.fragment_title, container, false)
        setHasOptionsMenu(true) // State that we want an overflow menu
        return binding.root
    }

    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { // Override onCreateOptionsMenu
        super.onCreateOptionsMenu(menu, inflater)
        inflater?.inflate(R.menu.overflow_menu, menu) // Feed in the xml resource you created
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean { // Override onOptionsItemSelected 
        return NavigationUI.onNavDestinationSelected(item!!, view!!.findNavController()) // Use the NavigationUI class to determine if you clicked an item in your list
                || super.onOptionsItemSelected(item) // If not, defer to super
    }
}

 

Up Navigation support in Navigation component

In Launcher Activity:

import ...

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        @Suppress("UNUSED_VARIABLE")
        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        val navController = this.findNavController(R.id.myNavHostFragment) // Find the NavController
        NavigationUI.setupActionBarWithNavController(this, navController) // Setup the ActionBar
    }

    override fun onSupportNavigateUp(): Boolean { // Override the Up Navigation
        val navController = this.findNavController(R.id.myNavHostFragment)
        return navController.navigateUp()
    }
}