├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── navigation
│ │ └── component
│ │ └── sample
│ │ ├── data
│ │ └── MyParcelableDataArgs.kt
│ │ └── ui
│ │ ├── activity
│ │ └── MainActivity.kt
│ │ ├── fragments
│ │ ├── DeepLinkFragment.kt
│ │ ├── MyHomeFragment.kt
│ │ ├── MySecondFragment.kt
│ │ ├── MyThirdFragment.kt
│ │ └── SettingsFragment.kt
│ │ └── widget
│ │ └── DeepLinkAppWidgetProvider.kt
│ └── res
│ ├── anim
│ ├── fade_in.xml
│ ├── fade_out.xml
│ ├── slide_in_left.xml
│ ├── slide_in_right.xml
│ ├── slide_out_left.xml
│ └── slide_out_right.xml
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable-xhdpi
│ ├── congrats.png
│ ├── ic_lets_start.png
│ └── wow.png
│ ├── drawable
│ ├── ic_android.xml
│ ├── ic_help.xml
│ ├── ic_home.xml
│ ├── ic_launcher_background.xml
│ ├── ic_settings.xml
│ └── ic_shopping_cart_white.xml
│ ├── layout-h470dp
│ └── navigation_activity.xml
│ ├── layout-w960dp
│ └── navigation_activity.xml
│ ├── layout
│ ├── activity_main.xml
│ ├── deep_link_appwidget.xml
│ ├── deeplink_fragment.xml
│ ├── fragment_my_home.xml
│ ├── fragment_my_second.xml
│ ├── fragment_my_third.xml
│ ├── nav_view_header.xml
│ ├── navigation_activity.xml
│ ├── settings_fragment.xml
│ └── shopping_fragment.xml
│ ├── menu
│ ├── bottom_nav_menu.xml
│ ├── main_menu.xml
│ ├── nav_drawer_menu.xml
│ └── overflow_menu.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── navigation
│ └── app_navigation.xml
│ ├── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ └── deep_link_appwidget_info.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | /.gradle
15 | /.idea
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NavigationComponentSample
2 | The Navigation Architecture Component simplifies implementing navigation, while also helping you visualize your app's navigation flow.
3 |
4 | 
5 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-android-extensions'
6 | apply plugin: "androidx.navigation.safeargs.kotlin"
7 |
8 | def nav_version = "2.1.0-beta01"
9 | def nav_version_ktx = "2.1.0-beta01"
10 |
11 | android {
12 | compileSdkVersion 28
13 | defaultConfig {
14 | applicationId "com.navigation.component.sample"
15 | minSdkVersion 21
16 | targetSdkVersion 28
17 | versionCode 1
18 | versionName "1.0"
19 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
20 | }
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | compileOptions {
28 | sourceCompatibility = 1.8
29 | targetCompatibility = 1.8
30 | }
31 |
32 | kotlinOptions {
33 | jvmTarget = "1.8"
34 | }
35 | }
36 |
37 | dependencies {
38 | implementation fileTree(dir: 'libs', include: ['*.jar'])
39 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
40 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
41 | implementation 'androidx.legacy:legacy-support-v4:1.0.0'
42 | testImplementation 'junit:junit:4.12'
43 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
44 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
45 | // Kotlin
46 | implementation "androidx.navigation:navigation-fragment-ktx:$nav_version_ktx"
47 | implementation "androidx.navigation:navigation-ui-ktx:$nav_version_ktx"
48 | implementation "com.google.android.material:material:$rootProject.materialVersion"
49 | implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
50 | implementation "androidx.recyclerview:recyclerview:$rootProject.recyclerVersion"
51 |
52 | implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/navigation/component/sample/data/MyParcelableDataArgs.kt:
--------------------------------------------------------------------------------
1 | package com.navigation.component.sample.data
2 |
3 | import android.os.Parcel
4 | import android.os.Parcelable
5 |
6 | data class MyParcelableDataArgs(val data1:Int): Parcelable {
7 | var data2: Long=1
8 | var data3: String?=null
9 | var data4: Int=1
10 |
11 | constructor(parcel: Parcel) : this(parcel.readInt()) {
12 | data2 = parcel.readLong()
13 | data3 = parcel.readString()
14 | data4 = parcel.readInt()
15 | }
16 |
17 | override fun writeToParcel(parcel: Parcel, flags: Int) {
18 | parcel.writeInt(data1)
19 | parcel.writeLong(data2)
20 | parcel.writeString(data3)
21 | parcel.writeInt(data4)
22 | }
23 |
24 | override fun describeContents(): Int {
25 | return 0
26 | }
27 |
28 | companion object CREATOR : Parcelable.Creator {
29 | override fun createFromParcel(parcel: Parcel): MyParcelableDataArgs {
30 | return MyParcelableDataArgs(parcel)
31 | }
32 |
33 | override fun newArray(size: Int): Array {
34 | return arrayOfNulls(size)
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/navigation/component/sample/ui/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.navigation.component.sample.ui.activity
18 |
19 | import android.content.res.Resources
20 | import android.os.Bundle
21 | import android.util.Log
22 | import android.view.Menu
23 | import android.view.MenuItem
24 | import android.widget.Toast
25 | import androidx.appcompat.app.AppCompatActivity
26 | import androidx.appcompat.widget.Toolbar
27 | import androidx.drawerlayout.widget.DrawerLayout
28 | import androidx.navigation.NavController
29 | import androidx.navigation.findNavController
30 | import androidx.navigation.fragment.NavHostFragment
31 | import androidx.navigation.ui.*
32 | import com.google.android.material.bottomnavigation.BottomNavigationView
33 | import com.google.android.material.navigation.NavigationView
34 | import com.navigation.component.sample.R
35 |
36 | /**
37 | * A simple activity demonstrating use of a NavHostFragment with a navigation drawer.
38 | */
39 | class MainActivity : AppCompatActivity() {
40 |
41 | private lateinit var appBarConfiguration : AppBarConfiguration
42 |
43 | override fun onCreate(savedInstanceState: Bundle?) {
44 | super.onCreate(savedInstanceState)
45 | setContentView(R.layout.navigation_activity)
46 |
47 | val toolbar = findViewById(R.id.toolbar)
48 | setSupportActionBar(toolbar)
49 |
50 | val host: NavHostFragment = supportFragmentManager
51 | .findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment? ?: return
52 |
53 | // Set up Action Bar
54 | val navController = host.navController
55 |
56 | appBarConfiguration = AppBarConfiguration(navController.graph)
57 |
58 | setupNavigationMenu(navController)
59 | // TODO STEP 9.5 - Create an AppBarConfiguration with the correct top-level destinations
60 | // You should also remove the old appBarConfiguration setup above
61 | val drawerLayout : DrawerLayout? = findViewById(R.id.drawer_layout)
62 | appBarConfiguration = AppBarConfiguration(
63 | setOf(R.id.myHomeFragment, R.id.deepLinkFragment),
64 | drawerLayout)
65 | // TODO END STEP 9.5
66 |
67 | setupActionBar(navController, appBarConfiguration)
68 |
69 |
70 | setupBottomNavMenu(navController)
71 |
72 | navController.addOnDestinationChangedListener { _, destination, _ ->
73 | val dest: String = try {
74 | resources.getResourceName(destination.id)
75 | } catch (e: Resources.NotFoundException) {
76 | Integer.toString(destination.id)
77 | }
78 |
79 | Toast.makeText(this@MainActivity, "Navigated to $dest",
80 | Toast.LENGTH_SHORT).show()
81 | Log.d("NavigationActivity", "Navigated to $dest")
82 | }
83 | }
84 |
85 | private fun setupBottomNavMenu(navController: NavController) {
86 |
87 | // TODO STEP 9.3 - Use NavigationUI to set up Bottom Nav
88 | val bottomNav = findViewById(R.id.bottom_nav_view)
89 | bottomNav?.setupWithNavController(navController)
90 | // TODO END STEP 9.3
91 | }
92 |
93 | private fun setupNavigationMenu(navController: NavController) {
94 | // TODO STEP 9.4 - Use NavigationUI to set up a Navigation View
95 | // // In split screen mode, you can drag this view out from the left
96 | // // This does NOT modify the actionbar
97 | val sideNavView = findViewById(R.id.nav_view)
98 | sideNavView?.setupWithNavController(navController)
99 | // TODO END STEP 9.4
100 | }
101 |
102 | private fun setupActionBar(navController: NavController,
103 | appBarConfig : AppBarConfiguration) {
104 | // TODO STEP 9.6 - Have NavigationUI handle what your ActionBar displays
105 | // // This allows NavigationUI to decide what label to show in the action bar
106 | // // By using appBarConfig, it will also determine whether to
107 | // // show the up arrow or drawer menu icon
108 | setupActionBarWithNavController(navController, appBarConfig)
109 | // TODO END STEP 9.6
110 | }
111 |
112 | override fun onCreateOptionsMenu(menu: Menu): Boolean {
113 | val retValue = super.onCreateOptionsMenu(menu)
114 | val navigationView = findViewById(R.id.nav_view)
115 | // The NavigationView already has these same navigation items, so we only add
116 | // navigation items to the menu here if there isn't a NavigationView
117 | if (navigationView == null) {
118 | menuInflater.inflate(R.menu.overflow_menu, menu)
119 | return true
120 | }
121 | return retValue
122 | }
123 |
124 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
125 | return super.onOptionsItemSelected(item)
126 | // TODO STEP 9.2 - Have Navigation UI Handle the item selection - make sure to delete
127 | // the old return statement above
128 | // // Have the NavigationUI look for an action or destination matching the menu
129 | // // item id and navigate there if found.
130 | // // Otherwise, bubble up to the parent.
131 | return item.onNavDestinationSelected(findNavController(R.id.my_nav_host_fragment))
132 | || super.onOptionsItemSelected(item)
133 | // TODO END STEP 9.2
134 | }
135 |
136 | // TODO STEP 9.7 - Have NavigationUI handle up behavior in the ActionBar
137 | override fun onSupportNavigateUp(): Boolean {
138 | // Allows NavigationUI to support proper up navigation or the drawer layout
139 | // drawer menu, depending on the situation
140 | return findNavController(R.id.my_nav_host_fragment).navigateUp(appBarConfiguration)
141 | }
142 | // TODO END STEP 9.7
143 | }
144 |
--------------------------------------------------------------------------------
/app/src/main/java/com/navigation/component/sample/ui/fragments/DeepLinkFragment.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.navigation.component.sample.ui.fragments
18 |
19 | import android.app.NotificationChannel
20 | import android.app.NotificationManager
21 | import android.content.Context
22 | import android.os.Build
23 | import android.os.Bundle
24 | import android.view.LayoutInflater
25 | import android.view.View
26 | import android.view.ViewGroup
27 | import android.widget.Button
28 | import android.widget.EditText
29 | import android.widget.TextView
30 | import androidx.core.app.NotificationCompat
31 | import androidx.fragment.app.Fragment
32 | import androidx.navigation.fragment.findNavController
33 | import com.navigation.component.sample.R
34 |
35 | /**
36 | * Fragment used to show how to deep link to a destination
37 | */
38 | class DeepLinkFragment : Fragment() {
39 | override fun onCreateView(
40 | inflater: LayoutInflater,
41 | container: ViewGroup?,
42 | savedInstanceState: Bundle?
43 | ): View? {
44 | return inflater.inflate(R.layout.deeplink_fragment, container, false)
45 | }
46 |
47 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
48 | super.onViewCreated(view, savedInstanceState)
49 |
50 | val textView = view.findViewById(R.id.text)
51 | textView.text = arguments?.getString("myarg")
52 |
53 | val notificationButton = view.findViewById