├── .directory
├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── navigationdemo
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── navigationdemo
│ │ │ └── MainActivity.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.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
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── navigationdemo
│ └── ExampleUnitTest.kt
├── bar
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── bar
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── bar
│ │ │ ├── BarFragment.kt
│ │ │ └── BarViewModel.kt
│ └── res
│ │ ├── layout
│ │ └── fragment_bar.xml
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── bar
│ └── ExampleUnitTest.java
├── build.gradle
├── foo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── foo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── foo
│ │ │ ├── FooFragment.kt
│ │ │ └── FooViewModel.kt
│ └── res
│ │ ├── layout
│ │ └── fragment_foo.xml
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── foo
│ └── ExampleUnitTest.java
├── gradle.properties
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── navigation
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── navigation
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ └── res
│ │ ├── navigation
│ │ └── nav_graph.xml
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── navigation
│ └── ExampleUnitTest.java
├── resources
├── Android Architecture.png
└── nav_graph.png
└── settings.gradle
/.directory:
--------------------------------------------------------------------------------
1 | [Dolphin]
2 | Timestamp=2019,5,26,10,8,16
3 | Version=4
4 |
5 | [Settings]
6 | HiddenFilesShown=true
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | .DS_Store
5 | /build
6 | /captures
7 | .externalNativeBuild
8 |
9 | !gradle-wrapper.jar
10 |
11 | *.class
12 | *.log
13 | .mtj.tmp/
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 | .idea
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Using The Navigation Component in a Single Activity Multi-Module Android App
2 | ## Summary
3 |
4 | Google has made a point not to dictate how you structure your app. However, surprisingly, they have now made recommendations to help guide developers. Since Jetpack was announced in May 17, 2017 the way Google recommends you structure the project and the semantic meaning of the Android components has been evolving.
5 |
6 | Each section below serves as an overview. Under each of the sections I provide all the resources I used to come to grips with what eventually became our architecture. So if the overviews are too brief please peruse the resources to get a better understanding.
7 |
8 | - [Jetpack](https://developer.android.com/jetpack)
9 |
10 | ## Single Activity Architecture
11 |
12 | One of the core components Jetpack introduced are the architecture components. The navigation component is one of these architecture components. The development of these architecture components lead to Google being more explicit with how to use Android components. Specifically, Google now officially recommend new Android applications are created as single activity applications.
13 |
14 | > Today we are introducing the Navigation component as a framework for structuring your in-app UI, with a focus on making a single-Activity app the preferred architecture.
15 |
16 | Google defines an activity as the entry point of your application. Therefore, having multiple activities indicates a user should be able to enter the app at the start of any one those activities.
17 |
18 | - [Single Activity: Why, When, and How](https://www.youtube.com/watch?v=2k8x8V77CrU&feature=youtu.be)
19 | - [A Single-Activity Android Application. Why not?!](https://medium.com/rosberryapps/a-single-activity-android-application-why-not-fa2a5458a099)
20 | - [Introducing Jetpack](https://android-developers.googleblog.com/2018/05/use-android-jetpack-to-accelerate-your.html?m=1)
21 |
22 | ## Multi-Module App
23 |
24 | Google also introduced a new application serving model called Dynamic Delivery. This defers APK generation to Google Play. Google Play uses Android App Bundles to create better optimized APKs for wider support. This now also gives developers the opportunity to use dynamic feature modules. Allowing certain features and assets to be downloaded later as the users need them.
25 |
26 | Over and above the obvious benefits of modular applications Dynamic Delivery creates a large incentive for designing modular apps. Furthermore, Google also recommends you modularize your apps.
27 |
28 | - [Build a Modular Android App Architecture (Google I/O'19)](https://www.youtube.com/watch?v=PZBg5DIzNww)
29 | - [Modularize your app](https://developer.android.com/studio/projects/dynamic-delivery#modularize)
30 | - [Intro to app modularization](https://proandroiddev.com/intro-to-app-modularization-42411e4c421e)
31 | - [Optimize your app](https://developer.android.com/studio/build/optimize-your-build)
32 |
33 | ## Jetpack | Architecture | Navigation Component
34 |
35 | > Jetpack is a suite of libraries, tools, and guidance to help developers write high-quality apps easier. These components help you follow best practices, free you from writing boilerplate code, and simplify complex tasks, so you can focus on the code you care about.
36 |
37 | Google introduced the navigation component as part of the Jetpack architecture components. This component handles fragment transactions, back stack management, transitions and animations, deep linking, and UI patterns.
38 |
39 | - [Navigation Getting Started](https://developer.android.com/guide/navigation/navigation-getting-started)
40 | - [Deeplinking with navigation component](https://medium.com/incwell-innovations/deeplink-and-navigation-in-android-architecture-component-part-3-b882ed5d5b32)
41 | - [Splash screen using the navigation component](https://proandroiddev.com/android-navigation-component-tips-tricks-implementing-splash-screen-f0f5ce046a09)
42 |
43 | ## Our solution
44 |
45 | Given the latest developments in Android we wanted to adhere to best practices as far as possible. This meant creating a modular, single activity app using the latest architecture components. However, there wasn't a lot of official documentation on using all of these best practices and structural recommendations together. So we struggled. But we tried to do it incrementally. And this is what we found.
46 |
47 | ### Modularization
48 |
49 | After some deliberation we settled on creating high-level feature modules with the intent of modularizing further when the need arises. We also had a module which depended on these feature modules and essentially coordinated them. Across the project there was a lot of code that was used by all the modules. Examples include the communication interfaces, navigation, input validations, and authentication. Therefore, a common module was created called _core_. The architecture can be visualized below.
50 |
51 | 
52 |
53 | _feature one_ has to be aware and therefore dependent on _feature two_ in order to navigate to it. Conversely, _feature two_ has to be aware and therefore dependent on _feature one_ in order to navigate to it. If this is a scenario then there will be circular dependency between the two features. Therefore, static objects were made in _core_ with interfaces defining navigation which could be consumed by the features. The _app_ feature then overrided the interface methods to define the behaviour. This was a gross way of solving navigation but it worked until we implemented the navigation component.
54 |
55 | ### Single Activity
56 |
57 | Initially we had two activities. One for login and another for the app's main page. After doing some reading it seemed Google recommended creating a single activity and swapping out fragments within that activity using the Navigation component. Since we wanted to solve the hacky navigation job it seemed single activity app architecture was the way to go.
58 |
59 | First off, we had to convert our existing activities to fragments. Then we had to create a new activity called _MainActivity_ - very creative, I know - which would then swap these activities in and out. At first this seemed quite straight forward, but there were a few gotchas.
60 |
61 | Most notably, we could no longer navigate to another screen which in this case was now a fragment. If we did want to navigate between fragments we would need to use the `FragmentManager` and `FragmentTransactions`. But this was a lot of work to be done only to be replaced by the navigation component. Therefore, for the time being our app could simply not navigate.
62 |
63 | Another issue was that `setSupportedToolbar` is a method which belongs to activities. So how the hell do we add toolbars to fragments? We ignored this problem in hopes that navigation components will maagically solve this for us, which they thankfully did.
64 |
65 | ### Jetpack | Architecture | Navigation Component
66 |
67 | Please go read up a bit on the navigational component if this doesn't make complete sense.
68 |
69 | The navigational component requires the following to be defined: navigation host, navigation graph, and navigation controller.
70 |
71 | #### Navigation host
72 |
73 | The navigation host is an empty container where the destinations are swapped in and out. This is typically an XML fragment. In our case the navigation host was located in the newly created _MainActivity_.
74 |
75 | #### Navigation graph
76 | The navigation graph is a resource which describes destinations (fragments) and those destinations' possible actions (moves to other destinations).
77 | Note that this doesn't create a direct dependency to the fragments but simply catalogs them using their fully qualified name.
78 |
79 | All features and fragments need full awareness of this navigation graph if they wish to navigate to a fragment defined in it. Therefore, this made the _core_ module the optimal place to keep the navigation graph.
80 |
81 | > 
82 |
83 | Typically you can use the navigation graph editor to detect the navigation host, add new destinations, and add new actions.
84 | However, due to the project being separated into multiple modules Android Studio isn't smart enough to detect the destinations and navigation host through the graph editor. Therefore, you do not have the luxury of using the graph editor but since the resources squash down to the same file, at compile time it all works itself out in the end.
85 |
86 | ### Navigation controller
87 |
88 | The navigation controller is an object provided by the navigation host. This can be accessed by a fragment, view, or activity. This simply gives you the ability to navigate to one of the destinations described in the navigation graph.
89 |
90 | - [Using Navigation Architecture Component in a large banking app](https://medium.com/google-developer-experts/using-navigation-architecture-component-in-a-large-banking-app-ac84936a42c2)
91 | - [A quick glance on single activity approach with navigation component](https://android.jlelse.eu/a-quick-glance-on-single-activity-approach-with-navigation-component-f3b96b3b0a58)
92 | - [GitHub | Navigation Single Activity](https://github.com/GabrielSamojlo/navigation-single-activity)
93 |
--------------------------------------------------------------------------------
/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 |
7 | android {
8 | compileSdkVersion 28
9 | defaultConfig {
10 | applicationId "com.example.navigationdemo"
11 | minSdkVersion 16
12 | targetSdkVersion 28
13 | versionCode 1
14 | versionName "1.0"
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation project(path: ':navigation')
27 | implementation project(path: ':foo')
28 | implementation project(path: ':bar')
29 |
30 | implementation fileTree(dir: 'libs', include: ['*.jar'])
31 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
32 | implementation 'androidx.appcompat:appcompat:1.0.2'
33 | implementation 'androidx.core:core-ktx:1.0.2'
34 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
35 | implementation 'androidx.legacy:legacy-support-v4:1.0.0'
36 | implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
37 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0'
38 | testImplementation 'junit:junit:4.12'
39 | androidTestImplementation 'androidx.test:runner:1.1.1'
40 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
41 | implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
42 | implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
43 | }
44 |
--------------------------------------------------------------------------------
/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/androidTest/java/com/example/navigationdemo/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.navigationdemo
2 |
3 | import androidx.test.InstrumentationRegistry
4 | import androidx.test.runner.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getTargetContext()
22 | assertEquals("com.example.navigationdemo", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/navigationdemo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.navigationdemo
2 |
3 | import androidx.appcompat.app.AppCompatActivity
4 | import android.os.Bundle
5 |
6 | class MainActivity : AppCompatActivity() {
7 |
8 | override fun onCreate(savedInstanceState: Bundle?) {
9 | super.onCreate(savedInstanceState)
10 | setContentView(R.layout.activity_main)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
22 |
24 |
26 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
44 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
68 |
70 |
72 |
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Navigation Demo
3 |
4 |
5 | Hello blank fragment
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/navigationdemo/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.navigationdemo
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/bar/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/bar/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 |
5 | android {
6 | compileSdkVersion 28
7 |
8 |
9 | defaultConfig {
10 | minSdkVersion 16
11 | targetSdkVersion 28
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation project(path: ':navigation')
30 |
31 | implementation fileTree(dir: 'libs', include: ['*.jar'])
32 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
33 | implementation 'androidx.appcompat:appcompat:1.0.2'
34 | implementation 'androidx.core:core-ktx:1.0.2'
35 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
36 | implementation 'androidx.legacy:legacy-support-v4:1.0.0'
37 | implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
38 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0'
39 | testImplementation 'junit:junit:4.12'
40 | androidTestImplementation 'androidx.test:runner:1.1.1'
41 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
42 | implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
43 | implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
44 | }
45 |
--------------------------------------------------------------------------------
/bar/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 |
--------------------------------------------------------------------------------
/bar/src/androidTest/java/com/example/bar/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.bar;
2 |
3 | import android.content.Context;
4 | import androidx.test.InstrumentationRegistry;
5 | import androidx.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.example.bar.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/bar/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/bar/src/main/java/com/example/bar/BarFragment.kt:
--------------------------------------------------------------------------------
1 | package com.example.bar
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import androidx.lifecycle.ViewModelProviders
9 |
10 | class BarFragment : Fragment() {
11 |
12 | companion object {
13 | fun newInstance() = BarFragment()
14 | }
15 |
16 | private lateinit var viewModel: BarViewModel
17 |
18 | override fun onCreateView(
19 | inflater: LayoutInflater, container: ViewGroup?,
20 | savedInstanceState: Bundle?
21 | ): View? {
22 | return inflater.inflate(R.layout.fragment_bar, container, false)
23 | }
24 |
25 | override fun onActivityCreated(savedInstanceState: Bundle?) {
26 | super.onActivityCreated(savedInstanceState)
27 | viewModel = ViewModelProviders.of(this).get(BarViewModel::class.java)
28 | // TODO: Use the ViewModel
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/bar/src/main/java/com/example/bar/BarViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.example.bar
2 |
3 | import androidx.lifecycle.ViewModel;
4 |
5 | class BarViewModel : ViewModel() {
6 | // TODO: Implement the ViewModel
7 | }
8 |
--------------------------------------------------------------------------------
/bar/src/main/res/layout/fragment_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/bar/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | bar
3 |
4 |
--------------------------------------------------------------------------------
/bar/src/test/java/com/example/bar/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.bar;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.31'
5 | repositories {
6 | google()
7 | jcenter()
8 |
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.4.1'
12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 |
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/foo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/foo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 |
5 | android {
6 | compileSdkVersion 28
7 |
8 |
9 | defaultConfig {
10 | minSdkVersion 16
11 | targetSdkVersion 28
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation project(path: ':navigation')
30 |
31 | implementation fileTree(dir: 'libs', include: ['*.jar'])
32 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
33 | implementation 'androidx.appcompat:appcompat:1.0.2'
34 | implementation 'androidx.core:core-ktx:1.0.2'
35 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
36 | implementation 'androidx.legacy:legacy-support-v4:1.0.0'
37 | implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
38 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0'
39 | testImplementation 'junit:junit:4.12'
40 | androidTestImplementation 'androidx.test:runner:1.1.1'
41 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
42 | implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
43 | implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
44 | }
45 |
--------------------------------------------------------------------------------
/foo/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 |
--------------------------------------------------------------------------------
/foo/src/androidTest/java/com/example/foo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.foo;
2 |
3 | import android.content.Context;
4 | import androidx.test.InstrumentationRegistry;
5 | import androidx.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.example.foo.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/foo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/foo/src/main/java/com/example/foo/FooFragment.kt:
--------------------------------------------------------------------------------
1 | package com.example.foo
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import androidx.lifecycle.ViewModelProviders
9 | import androidx.navigation.fragment.findNavController
10 | import kotlinx.android.synthetic.main.fragment_foo.*
11 |
12 | class FooFragment : Fragment() {
13 |
14 | companion object {
15 | fun newInstance() = FooFragment()
16 | }
17 |
18 | private lateinit var viewModel: FooViewModel
19 |
20 | override fun onCreateView(
21 | inflater: LayoutInflater, container: ViewGroup?,
22 | savedInstanceState: Bundle?
23 | ): View? {
24 | return inflater.inflate(R.layout.fragment_foo, container, false)
25 | }
26 |
27 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
28 | super.onViewCreated(view, savedInstanceState)
29 |
30 | go_somwhere_button.setOnClickListener { findNavController().navigate(R.id.barFragment) }
31 | }
32 |
33 | override fun onActivityCreated(savedInstanceState: Bundle?) {
34 | super.onActivityCreated(savedInstanceState)
35 | viewModel = ViewModelProviders.of(this).get(FooViewModel::class.java)
36 | // TODO: Use the ViewModel
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/foo/src/main/java/com/example/foo/FooViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.example.foo
2 |
3 | import androidx.lifecycle.ViewModel;
4 |
5 | class FooViewModel : ViewModel() {
6 | // TODO: Implement the ViewModel
7 | }
8 |
--------------------------------------------------------------------------------
/foo/src/main/res/layout/fragment_foo.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
27 |
--------------------------------------------------------------------------------
/foo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Foo
3 |
4 |
--------------------------------------------------------------------------------
/foo/src/test/java/com/example/foo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.foo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu May 23 09:48:55 SAST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/navigation/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/navigation/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 28
5 |
6 |
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 28
10 | versionCode 1
11 | versionName "1.0"
12 |
13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
14 |
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 |
24 | }
25 |
26 | dependencies {
27 | implementation fileTree(dir: 'libs', include: ['*.jar'])
28 |
29 | implementation 'androidx.appcompat:appcompat:1.0.2'
30 | testImplementation 'junit:junit:4.12'
31 | androidTestImplementation 'androidx.test:runner:1.1.1'
32 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
33 | implementation 'androidx.navigation:navigation-fragment:2.0.0'
34 | implementation 'androidx.navigation:navigation-ui:2.0.0'
35 | }
36 |
--------------------------------------------------------------------------------
/navigation/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 |
--------------------------------------------------------------------------------
/navigation/src/androidTest/java/com/example/navigation/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.navigation;
2 |
3 | import android.content.Context;
4 | import androidx.test.InstrumentationRegistry;
5 | import androidx.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.example.navigation.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/navigation/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/navigation/src/main/res/navigation/nav_graph.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
10 |
11 |
12 |
14 |
15 |
--------------------------------------------------------------------------------
/navigation/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Navigation
3 |
4 |
--------------------------------------------------------------------------------
/navigation/src/test/java/com/example/navigation/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.navigation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/resources/Android Architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/resources/Android Architecture.png
--------------------------------------------------------------------------------
/resources/nav_graph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuartBreedt/Android-Navigation-in-a-Single-Activity-Multi-Module-App/c6ee8f773278cd8120acfdafd15d9959ddd59989/resources/nav_graph.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':foo', ':bar', ':navigation'
2 |
--------------------------------------------------------------------------------