1 of 52

1

Lesson 6:

App navigation

This work is licensed under the Apache 2 license.

Android Development with Kotlin v1.0

This work is licensed under the Apache 2 license.

2 of 52

About this lesson

Lesson 6: App navigation

2

Android Development with Kotlin

This work is licensed under the Apache 2 license.

3 of 52

3

Multiple activities and intents

Android Development with Kotlin

This work is licensed under the Apache 2 license.

4 of 52

Multiple screens in an app

Sometimes app functionality may be separated into multiple screens.

�Examples:

  • View details of a single item (for example, product in a shopping app)
  • Create a new item (for example, new email)
  • Show settings for an app
  • Access services in other apps (for example, photo gallery or browse documents)

4

Android Development with Kotlin

This work is licensed under the Apache 2 license.

5 of 52

Intent

Requests an action from another app component, such as another Activity

  • An Intent usually has two primary pieces of information:
    • Action to be performed (for example, ACTION_VIEW, ACTION_EDIT, ACTION_MAIN)
    • Data to operate on (for example, a person’s record in the contacts database)
  • Commonly used to specify a request to transition to another Activity

5

Android Development with Kotlin

This work is licensed under the Apache 2 license.

6 of 52

Explicit intent

  • Fulfills a request using a specific component
  • Navigates internally to an Activity in your app
  • Navigates to a specific third-party app or another app you've written

6

Android Development with Kotlin

This work is licensed under the Apache 2 license.

7 of 52

Explicit intent examples

Navigate between activities in your app:

fun viewNoteDetail() {

val intent = Intent(this, NoteDetailActivity::class.java)

intent.putExtra(NOTE_ID, note.id)

startActivity(intent)

}

7

Navigate to a specific external app:

fun openExternalApp() {

val intent = Intent("com.example.workapp.FILE_OPEN")

if (intent.resolveActivity(packageManager) != null) {

startActivity(intent)

}

}

Android Development with Kotlin

This work is licensed under the Apache 2 license.

8 of 52

Implicit intent

  • Provides generic action the app can perform
  • Resolved using mapping of the data type and action to known components
  • Allows any app that matches the criteria to handle the request

8

Android Development with Kotlin

This work is licensed under the Apache 2 license.

9 of 52

Implicit intent example

fun sendEmail() {

val intent = Intent(Intent.ACTION_SEND)

intent.type = "text/plain"

intent.putExtra(Intent.EXTRA_EMAIL, emailAddresses)

intent.putExtra(Intent.EXTRA_TEXT, "How are you?")

if (intent.resolveActivity(packageManager) != null) {

startActivity(intent)

}

}

9

Android Development with Kotlin

This work is licensed under the Apache 2 license.

10 of 52

10

App bar, navigation drawer, and menus

Android Development with Kotlin

This work is licensed under the Apache 2 license.

11 of 52

App bar

11

Android Development with Kotlin

This work is licensed under the Apache 2 license.

12 of 52

Navigation drawer

12

Android Development with Kotlin

This work is licensed under the Apache 2 license.

13 of 52

Menu

Define menu items in XML menu resource (located in res/menu folder)

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

xmlns:app="http://schemas.android.com/apk/res-auto">

<item

android:id="@+id/action_settings"

android:orderInCategory="100"

android:title="@string/action_settings"

app:showAsAction="never" />

</menu>

13

Android Development with Kotlin

This work is licensed under the Apache 2 license.

14 of 52

More menu options

<menu>

<group android:checkableBehavior="single">

<item

android:id="@+id/nav_home"

android:icon="@drawable/ic_menu_camera"

android:title="@string/menu_home" />

<item

android:id="@+id/nav_gallery"

android:icon="@drawable/ic_menu_gallery"

android:title="@string/menu_gallery" />

<item

android:id="@+id/nav_slideshow"

android:icon="@drawable/ic_menu_slideshow"

android:title="@string/menu_slideshow" />

</group>

</menu>

14

Android Development with Kotlin

This work is licensed under the Apache 2 license.

15 of 52

Options menu example

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

xmlns:app="http://schemas.android.com/apk/res-auto">

<item android:id="@+id/action_intent"

android:title="@string/action_intent" />

<item

android:id="@+id/action_settings"

android:orderInCategory="100"

android:title="@string/action_settings"

app:showAsAction="never" />

</menu>

15

Android Development with Kotlin

This work is licensed under the Apache 2 license.

16 of 52

Inflate options menu

override fun onCreateOptionsMenu(menu: Menu): Boolean {

menuInflater.inflate(R.menu.main, menu)

return true

}

16

Android Development with Kotlin

This work is licensed under the Apache 2 license.

17 of 52

Handle menu options selected

17

override fun onOptionsItemSelected(item: MenuItem): Boolean {

when (item.itemId) {

R.id.action_intent -> {

val intent = Intent(Intent.ACTION_WEB_SEARCH)

intent.putExtra(SearchManager.QUERY, "pizza")

if (intent.resolveActivity(packageManager) != null) {

startActivity(intent)

}

}

else -> Toast.makeText(this, item.title, Toast.LENGTH_LONG).show()

...

Android Development with Kotlin

This work is licensed under the Apache 2 license.

18 of 52

18

Fragments

Android Development with Kotlin

This work is licensed under the Apache 2 license.

19 of 52

Fragments for tablet layouts

19

Android Development with Kotlin

This work is licensed under the Apache 2 license.

20 of 52

Fragment

  • Represents a behavior or portion of the UI in an activity �("microactivity")
  • Must be hosted in an activity
  • Lifecycle tied to host activity's lifecycle
  • Can be added or removed at runtime

20

Android Development with Kotlin

This work is licensed under the Apache 2 license.

21 of 52

Note about fragments

Use the AndroidX version of the Fragment class. (androidx.fragment.app.Fragment).

Don't use the platform version of the Fragment class (android.app.Fragment), which was deprecated.

21

Android Development with Kotlin

This work is licensed under the Apache 2 license.

22 of 52

Navigation within an app

22

Android Development with Kotlin

This work is licensed under the Apache 2 license.

23 of 52

Navigation component

  • Collection of libraries and tooling, including an integrated editor, for creating navigation paths through an app
  • Assumes one Activity per graph with many Fragment destinations
  • Consists of three major parts:
    • Navigation graph
    • Navigation Host (NavHost)
    • Navigation Controller (NavController)

23

Android Development with Kotlin

This work is licensed under the Apache 2 license.

24 of 52

Add dependencies

implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"

implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

24

In build.gradle, under dependencies:

Android Development with Kotlin

This work is licensed under the Apache 2 license.

25 of 52

Navigation host (NavHost)

<fragment

android:id="@+id/nav_host"

android:name="androidx.navigation.fragment.NavHostFragment"

android:layout_width="match_parent"

android:layout_height="match_parent"

app:defaultNavHost="true"

app:navGraph="@navigation/nav_graph_name"/>

25

Android Development with Kotlin

This work is licensed under the Apache 2 license.

26 of 52

Navigation graph

New resource type located in res/navigation directory

  • XML file containing all of your navigation destinations and actions
  • Lists all the (Fragment/Activity) destinations that can be navigated to
  • Lists the associated actions to traverse between them
  • Optionally lists animations for entering or exiting

26

Android Development with Kotlin

This work is licensed under the Apache 2 license.

27 of 52

Navigation Editor in Android Studio

27

Android Development with Kotlin

This work is licensed under the Apache 2 license.

28 of 52

Creating a Fragment

  • Extend Fragment class
  • Override onCreateView()
  • Inflate a layout for the Fragment that you have defined in XML

28

class DetailFragment : Fragment() {

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,

savedInstanceState: Bundle?): View? {

return inflater.inflate(R.layout.detail_fragment, container, false)

}

}

Android Development with Kotlin

This work is licensed under the Apache 2 license.

29 of 52

Specifying Fragment destinations

29

  • Fragment destinations are denoted by the action tag in the navigation graph.
  • Actions can be defined in XML directly or in the Navigation Editor by dragging from source to destination.
  • Autogenerated action IDs take the form of action_<sourceFragment>_to_<destinationFragment>.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

30 of 52

Example fragment destination

30

<fragment

android:id="@+id/welcomeFragment"

android:name="com.example.android.navigation.WelcomeFragment"

android:label="fragment_welcome"

tools:layout="@layout/fragment_welcome" >

<action

android:id="@+id/action_welcomeFragment_to_detailFragment"

app:destination="@id/detailFragment" />

</fragment>

Android Development with Kotlin

This work is licensed under the Apache 2 license.

31 of 52

Navigation Controller (NavController)

NavController manages UI navigation in a navigation host.

  • Specifying a destination path only names the action, but it doesn’t execute it.
  • To follow a path, use NavController.

31

Android Development with Kotlin

This work is licensed under the Apache 2 license.

32 of 52

Example NavController

32

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

...

val navController = findNavController(R.id.myNavHostFragment)

}

fun navigateToDetail() {

navController.navigate(R.id.action_welcomeFragment_to_detailFragment)

}

}

Android Development with Kotlin

This work is licensed under the Apache 2 license.

33 of 52

More custom navigation behavior

33

Android Development with Kotlin

This work is licensed under the Apache 2 license.

34 of 52

Passing data between destinations

Using Safe Args:

  • Ensures arguments have a valid type
  • Lets you provide default values
  • Generates a <SourceDestination>Directions class with methods for every action in that destination
  • Generates a class to set arguments for every named action
  • Generates a <TargetDestination>Args class providing access to the destination's arguments

34

Android Development with Kotlin

This work is licensed under the Apache 2 license.

35 of 52

Setting up Safe Args

In the project build.gradle file:

35

buildscript {

repositories {

google()

}

dependencies {

classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"

}

}

In the app's or module's build.gradle file:

apply plugin: "androidx.navigation.safeargs.kotlin"

Android Development with Kotlin

This work is licensed under the Apache 2 license.

36 of 52

Sending data to a Fragment

  1. Create arguments the destination fragment will expect.
  2. Create action to link from source to destination.
  3. Set the arguments in the action method on <Source>FragmentDirections.
  4. Navigate according to that action using the Navigation Controller.
  5. Retrieve the arguments in the destination fragment.

36

Android Development with Kotlin

This work is licensed under the Apache 2 license.

37 of 52

Destination arguments

37

<fragment

android:id="@+id/multiplyFragment"

android:name="com.example.arithmetic.MultiplyFragment"

android:label="MultiplyFragment" >

<argument

android:name="number1"

app:argType="float"

android:defaultValue="1.0" />

<argument

android:name="number2"

app:argType="float"

android:defaultValue="1.0" />

</fragment>

Android Development with Kotlin

This work is licensed under the Apache 2 license.

38 of 52

Supported argument types

38

Type

Type Syntax

app:argType=<type>

Supports Default

Values

Supports Null

Values

Integer

"integer"

Yes

No

Float

"float"

Yes

No

Long

"long"

Yes

No

Boolean

"boolean"

Yes ("true" or "false")

No

String

"string"

Yes

Yes

Array

above type + "[]"

(for example, "string[]" "long[]")

Yes (only "@null")

Yes

Enum

Fully qualified name of the enum

Yes

No

Resource reference

"reference"

Yes

No

Android Development with Kotlin

This work is licensed under the Apache 2 license.

39 of 52

Supported argument types: Custom classes

39

Type

Type Syntax

app:argType=<type>

Supports Default

Values

Supports Null

Values

Serializable

Fully qualified class name

Yes (only "@null")

Yes

Parcelable

Fully qualified class name

Yes (only "@null")

Yes

Android Development with Kotlin

This work is licensed under the Apache 2 license.

40 of 52

Create action from source to destination

<fragment

android:id="@+id/fragment_input"

android:name="com.example.arithmetic.InputFragment">

<action

android:id="@+id/action_to_multiplyFragment"

app:destination="@id/multiplyFragment" />

</fragment>

40

In nav_graph.xml:

Android Development with Kotlin

This work is licensed under the Apache 2 license.

41 of 52

Navigating with actions

In InputFragment.kt:

41

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

super.onViewCreated(view, savedInstanceState)

binding.button.setOnClickListener {

val n1 = binding.number1.text.toString().toFloatOrNull() ?: 0.0

val n2 = binding.number2.text.toString().toFloatOrNull() ?: 0.0

val action = InputFragmentDirections.actionToMultiplyFragment(n1, n2)

view.findNavController().navigate(action)

}

}

Android Development with Kotlin

This work is licensed under the Apache 2 license.

42 of 52

Retrieving Fragment arguments

class MultiplyFragment : Fragment() {

val args: MultiplyFragmentArgs by navArgs()

lateinit var binding: FragmentMultiplyBinding

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

super.onViewCreated(view, savedInstanceState)

val number1 = args.number1

val number2 = args.number2

val result = number1 * number2

binding.output.text = "${number1} * ${number2} = ${result}"

}

}

42

Android Development with Kotlin

This work is licensed under the Apache 2 license.

43 of 52

Navigation UI

43

Android Development with Kotlin

This work is licensed under the Apache 2 license.

44 of 52

Menus revisited

override fun onOptionsItemSelected(item: MenuItem): Boolean {

val navController = findNavController(R.id.nav_host_fragment)

return item.onNavDestinationSelected(navController) ||

super.onOptionsItemSelected(item)

}

44

Android Development with Kotlin

This work is licensed under the Apache 2 license.

45 of 52

DrawerLayout for navigation drawer

<androidx.drawerlayout.widget.DrawerLayout

android:id="@+id/drawer_layout" ...>

<fragment

android:name="androidx.navigation.fragment.NavHostFragment"

android:id="@+id/nav_host_fragment" ... />

<com.google.android.material.navigation.NavigationView

android:id="@+id/nav_view"

app:menu="@menu/activity_main_drawer" ... />

</androidx.drawerlayout.widget.DrawerLayout>

45

Android Development with Kotlin

This work is licensed under the Apache 2 license.

46 of 52

Finish setting up navigation drawer

Connect DrawerLayout to navigation graph:

val appBarConfiguration = AppBarConfig(navController.graph, drawer)

46

Set up NavigationView for use with a NavController:

val navView = findViewById<NavigationView>(R.id.nav_view)

navView.setupWithNavController(navController)

Android Development with Kotlin

This work is licensed under the Apache 2 license.

47 of 52

Understanding the back stack

Back stack

Activity 1

Activity 2

Back stack

Activity 1

Back stack

Activity 2

Activity 1

Activity 2

Activity 3

State 1

State 3

State 2

Android Development with Kotlin

This work is licensed under the Apache 2 license.

48 of 52

Fragments and the back stack

Back stack

Activity 1

Activity 2

Fragment 1

Back stack

Activity 1

Activity 2

Fragment 1

Fragment 2

Back stack

Activity 1

Activity 2

Fragment 1

State 1

State 3

State 2

Android Development with Kotlin

This work is licensed under the Apache 2 license.

49 of 52

49

Summary

Android Development with Kotlin

This work is licensed under the Apache 2 license.

50 of 52

Summary

50

Android Development with Kotlin

This work is licensed under the Apache 2 license.

51 of 52

Learn more

51

Android Development with Kotlin

This work is licensed under the Apache 2 license.

52 of 52

Pathway

Practice what you’ve learned by�completing the pathway:

Lesson 6: App navigation

52

Android Development with Kotlin

This work is licensed under the Apache 2 license.