Bird
Raised Fist0
Android Kotlinmobile~20 mins

Why navigation manages app flow in Android Kotlin - Build It to Prove It

Choose your learning style10 modes available
Build: Simple Navigation Flow
This screen demonstrates how navigation controls the flow between two screens in an Android app using Kotlin. It shows why navigation is important to move between different parts of the app smoothly.
Target UI
Screen 1: Home Screen
+---------------------+
|     Home Screen     |
|                     |
|  [Go to Details]    |
+---------------------+

Screen 2: Details Screen
+---------------------+
|   Details Screen    |
|                     |
|  [Back to Home]     |
+---------------------+
Create two screens: Home and Details
Home screen has a button labeled 'Go to Details' that navigates to Details screen
Details screen has a button labeled 'Back to Home' that navigates back to Home screen
Use Android Navigation Component to manage navigation
Show how navigation manages app flow by moving between screens
Starter Code
Android Kotlin
package com.example.navigationflow

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

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // TODO: Setup navigation host fragment
    }
}

// TODO: Create HomeFragment and DetailsFragment with buttons
Task 1
Task 2
Task 3
Task 4
Solution
Android Kotlin
package com.example.navigationflow

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupActionBarWithNavController
import com.example.navigationflow.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

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

    override fun onSupportNavigateUp(): Boolean {
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        val navController = navHostFragment.navController
        return navController.navigateUp() || super.onSupportNavigateUp()
    }
}

// HomeFragment.kt
package com.example.navigationflow

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 com.example.navigationflow.databinding.FragmentHomeBinding

class HomeFragment : Fragment() {
    private var _binding: FragmentHomeBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        _binding = FragmentHomeBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.buttonGoToDetails.setOnClickListener {
            findNavController().navigate(R.id.action_homeFragment_to_detailsFragment)
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

// DetailsFragment.kt
package com.example.navigationflow

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 com.example.navigationflow.databinding.FragmentDetailsBinding

class DetailsFragment : Fragment() {
    private var _binding: FragmentDetailsBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        _binding = FragmentDetailsBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.buttonBackToHome.setOnClickListener {
            findNavController().navigateUp()
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

// navigation/nav_graph.xml
<?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/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.navigationflow.HomeFragment"
        android:label="Home Screen">
        <action
            android:id="@+id/action_homeFragment_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>

    <fragment
        android:id="@+id/detailsFragment"
        android:name="com.example.navigationflow.DetailsFragment"
        android:label="Details Screen" />
</navigation>

// layout/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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

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

</androidx.constraintlayout.widget.ConstraintLayout>

// layout/fragment_home.xml
<?xml version="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:orientation="vertical"
    android:gravity="center"
    android:padding="16dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Home Screen"
        android:textSize="24sp"
        android:layout_marginBottom="24dp" />

    <Button
        android:id="@+id/buttonGoToDetails"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go to Details" />
</LinearLayout>

// layout/fragment_details.xml
<?xml version="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:orientation="vertical"
    android:gravity="center"
    android:padding="16dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Details Screen"
        android:textSize="24sp"
        android:layout_marginBottom="24dp" />

    <Button
        android:id="@+id/buttonBackToHome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Back to Home" />
</LinearLayout>

This app uses the Android Navigation Component to manage the flow between two screens: Home and Details.

The NavHostFragment in the main activity hosts the navigation graph, which defines the start screen and possible navigation paths.

In HomeFragment, a button triggers navigation to DetailsFragment using findNavController().navigate(). In DetailsFragment, the back button uses navigateUp() to return to Home.

This setup shows how navigation manages app flow by controlling which screen is shown and how users move between them, keeping the app organized and easy to follow.

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

Screen 2: Details Screen
+---------------------+
|   Details Screen    |
|                     |
|  [Back to Home]     |
+---------------------+
Tap 'Go to Details' button on Home Screen navigates to Details Screen
Tap 'Back to Home' button on Details Screen navigates back to Home Screen
Stretch Goal
Add a third screen called About with a button on Home Screen to navigate to it and a back button to return.
💡 Hint
Create AboutFragment and add it to the navigation graph. Add a button in HomeFragment that navigates to AboutFragment using findNavController().navigate().

Practice

(1/5)
1. Why is navigation important in an Android app?
Navigation helps users move between screens smoothly. What is its main purpose?
easy
A. To store user data securely
B. To change the app's color scheme automatically
C. To speed up the app's loading time
D. To control how users move between different screens

Solution

  1. Step 1: Understand navigation role

    Navigation manages the flow between screens in an app, guiding users.
  2. Step 2: Identify main purpose

    Its main purpose is to control user movement between screens, not visual or data tasks.
  3. Final Answer:

    To control how users move between different screens -> Option D
  4. Quick Check:

    Navigation = control user movement [OK]
Hint: Navigation controls screen flow, not colors or data [OK]
Common Mistakes:
  • Confusing navigation with UI styling
  • Thinking navigation speeds up loading
  • Mixing navigation with data storage
2. Which Kotlin code snippet correctly starts navigation to a new screen called DetailsFragment using Navigation Component?
easy
A. navigateTo(DetailsFragment())
B. findNavController().navigate(R.id.action_to_detailsFragment)
C. startActivity(Intent(this, DetailsFragment::class.java))
D. openScreen("DetailsFragment")

Solution

  1. Step 1: Identify Navigation Component syntax

    Using Navigation Component, navigation is done with findNavController().navigate() and action ID.
  2. Step 2: Match correct code

    findNavController().navigate(R.id.action_to_detailsFragment) uses correct method and action ID format for navigation.
  3. Final Answer:

    findNavController().navigate(R.id.action_to_detailsFragment) -> Option B
  4. Quick Check:

    Navigation Component uses findNavController().navigate() [OK]
Hint: Navigation Component uses findNavController().navigate() [OK]
Common Mistakes:
  • Using startActivity instead of Navigation Component
  • Calling non-existent navigateTo() method
  • Passing string instead of action ID
3. Given this code snippet inside a Fragment:
view.findNavController().navigate(R.id.action_home_to_profile)

What happens when this code runs?
medium
A. The app navigates from Home screen to Profile screen
B. The app crashes due to missing navigation controller
C. Nothing happens because the code is incomplete
D. The app opens a new activity instead of fragment

Solution

  1. Step 1: Understand navigate() call

    Calling navigate() with action ID triggers navigation between fragments.
  2. Step 2: Identify action meaning

    Action ID 'action_home_to_profile' means moving from Home to Profile screen.
  3. Final Answer:

    The app navigates from Home screen to Profile screen -> Option A
  4. Quick Check:

    navigate() with action ID changes screen [OK]
Hint: navigate() with action ID moves between screens [OK]
Common Mistakes:
  • Assuming code crashes without NavController
  • Thinking code does nothing without extra setup
  • Confusing fragment navigation with activity launch
4. This code tries to navigate but causes a crash:
view.findNavController().navigate(R.id.action_invalid)

What is the likely cause?
medium
A. The app lacks internet permission
B. The view is null when calling findNavController()
C. The action ID does not exist in navigation graph
D. The fragment is not attached to activity

Solution

  1. Step 1: Analyze navigation action ID

    Using an invalid action ID not defined in navigation graph causes crash.
  2. Step 2: Rule out other causes

    Null view or fragment issues cause different errors; internet permission unrelated.
  3. Final Answer:

    The action ID does not exist in navigation graph -> Option C
  4. Quick Check:

    Invalid action ID crashes navigation [OK]
Hint: Check action IDs exist in navigation graph [OK]
Common Mistakes:
  • Assuming null view causes this specific crash
  • Blaming fragment attachment without evidence
  • Confusing permissions with navigation errors
5. You want to ensure users cannot go back to the login screen after successful login using navigation. Which approach manages this app flow correctly?
hard
A. Use popUpTo with inclusive=true to remove login from back stack
B. Call finish() on login fragment after navigation
C. Disable back button in the app globally
D. Navigate to login screen again after logout

Solution

  1. Step 1: Understand back stack behavior

    Navigation back stack keeps screens; to prevent back to login, remove it from stack.
  2. Step 2: Use popUpTo with inclusive=true

    This removes login screen from back stack, so back button skips it.
  3. Step 3: Rule out other options

    finish() is for activities, disabling back globally is bad UX, navigating again doesn't prevent back.
  4. Final Answer:

    Use popUpTo with inclusive=true to remove login from back stack -> Option A
  5. Quick Check:

    popUpTo inclusive=true manages back stack correctly [OK]
Hint: Use popUpTo inclusive=true to clear unwanted back screens [OK]
Common Mistakes:
  • Trying to finish fragments instead of managing back stack
  • Disabling back button breaks user experience
  • Navigating again doesn't remove previous screens
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard