0
0
Android Kotlinmobile~20 mins

NavHost and NavController in Android Kotlin - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Simple Navigation Screen
This screen demonstrates basic navigation between two screens using NavHost and NavController in Android with Kotlin.
Target UI
Screen 1:
+---------------------+
|    Welcome Screen   |
|                     |
|  [Go to Details]    |
+---------------------+

Screen 2:
+---------------------+
|    Details Screen   |
|                     |
|  [Back to Welcome]  |
+---------------------+
Use NavHostFragment to host navigation
Use NavController to navigate between two fragments
First fragment has a button labeled 'Go to Details' that navigates to second fragment
Second fragment has a button labeled 'Back to Welcome' that navigates back
Use safe args or simple navigation actions
Use Kotlin and AndroidX Navigation components
Starter Code
Android Kotlin
package com.example.navigationdemo

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // TODO: Setup NavHostFragment and NavController
    }
}

// TODO: Create two fragments: WelcomeFragment and DetailsFragment
// Each fragment should have a button to navigate
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
Android Kotlin
package com.example.navigationdemo

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.NavController

class MainActivity : AppCompatActivity() {
    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val navHostFragment = supportFragmentManager
            .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        navController = navHostFragment.navController
    }
}

// WelcomeFragment.kt
package com.example.navigationdemo

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import android.widget.Button

class WelcomeFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_welcome, container, false)
        val button = view.findViewById<Button>(R.id.button_go_to_details)
        button.setOnClickListener {
            findNavController().navigate(R.id.action_welcomeFragment_to_detailsFragment)
        }
        return view
    }
}

// DetailsFragment.kt
package com.example.navigationdemo

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import android.widget.Button

class DetailsFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_details, container, false)
        val button = view.findViewById<Button>(R.id.button_back_to_welcome)
        button.setOnClickListener {
            findNavController().navigate(R.id.action_detailsFragment_to_welcomeFragment)
        }
        return view
    }
}

// activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

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

</androidx.constraintlayout.widget.ConstraintLayout>

// fragment_welcome.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <Button
        android:id="@+id/button_go_to_details"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go to Details"
        android:layout_gravity="center" />

</FrameLayout>

// fragment_details.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <Button
        android:id="@+id/button_back_to_welcome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Back to Welcome"
        android:layout_gravity="center" />

</FrameLayout>

// nav_graph.xml (in res/navigation)
<?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"
    android:id="@+id/nav_graph"
    app:startDestination="@id/welcomeFragment">

    <fragment
        android:id="@+id/welcomeFragment"
        android:name="com.example.navigationdemo.WelcomeFragment"
        android:label="Welcome">
        <action
            android:id="@+id/action_welcomeFragment_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>

    <fragment
        android:id="@+id/detailsFragment"
        android:name="com.example.navigationdemo.DetailsFragment"
        android:label="Details">
        <action
            android:id="@+id/action_detailsFragment_to_welcomeFragment"
            app:destination="@id/welcomeFragment" />
    </fragment>

</navigation>

This solution uses Android's Navigation component to manage navigation between two fragments.

The NavHostFragment is placed in the activity's layout to host the navigation graph. The NavController is obtained from the NavHostFragment in MainActivity.

Two fragments are created: WelcomeFragment and DetailsFragment. Each fragment has a button that triggers navigation actions defined in the navigation graph XML (nav_graph.xml).

When the user taps the button in WelcomeFragment, the app navigates to DetailsFragment. The button in DetailsFragment navigates back to WelcomeFragment.

This setup follows Android best practices for navigation, keeping UI and navigation logic clean and separate.

Final Result
Completed Screen
Screen 1:
+---------------------+
|    Welcome Screen   |
|                     |
|  [Go to Details]    |
+---------------------+

Screen 2:
+---------------------+
|    Details Screen   |
|                     |
|  [Back to Welcome]  |
+---------------------+
Tap 'Go to Details' button navigates from Welcome Screen to Details Screen
Tap 'Back to Welcome' button navigates back to Welcome Screen
Stretch Goal
Add a toolbar with a title that updates based on the current screen
💡 Hint
Use NavigationUI.setupActionBarWithNavController in MainActivity and override onSupportNavigateUp to handle back navigation