├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── colors.xml │ │ │ └── styles.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 │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ └── drawable │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ └── com │ │ │ └── mi │ │ │ └── best_practice │ │ │ ├── koin │ │ │ └── AppComponent.kt │ │ │ └── App.kt │ │ └── AndroidManifest.xml ├── build.gradle.kts └── proguard-rules.pro ├── dashboard ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── dimens.xml │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── menu │ │ │ │ └── menu_main.xml │ │ │ ├── layout │ │ │ │ ├── content_main.xml │ │ │ │ ├── fragment_second.xml │ │ │ │ ├── fragment_first.xml │ │ │ │ └── activity_dashboard.xml │ │ │ └── navigation │ │ │ │ └── nav_graph.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── mi │ │ │ │ └── dashboard │ │ │ │ ├── DashboardViewModel.kt │ │ │ │ ├── koin │ │ │ │ └── FeatureDashboardModule.kt │ │ │ │ ├── FirstFragment.kt │ │ │ │ ├── SecondFragment.kt │ │ │ │ └── MainActivity.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── mi │ │ │ └── dashboard │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── mi │ │ └── dashboard │ │ └── ExampleInstrumentedTest.kt ├── build.gradle.kts └── proguard-rules.pro ├── navigation ├── .gitignore ├── consumer-rules.pro ├── build.gradle.kts ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── mi │ │ │ └── navigation │ │ │ ├── ExtraConstant.kt │ │ │ └── Navigation.kt │ │ └── AndroidManifest.xml └── proguard-rules.pro ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle.kts ├── .gitignore ├── README.md ├── local.properties ├── gradle.properties ├── gradlew.bat ├── gradlew └── config └── detekt.yml /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /dashboard/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /navigation/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /navigation/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16dp 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Best Practice 3 | 4 | -------------------------------------------------------------------------------- /navigation/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id(GradlePluginId.ANDROID_LIB) 3 | id(GradlePluginId.BASE_GRADLE_PLUGIN) 4 | } 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /navigation/src/main/java/com/mi/navigation/ExtraConstant.kt: -------------------------------------------------------------------------------- 1 | package com.mi.navigation 2 | 3 | const val EXTRA_USER = "com.mi.navigation.dashboard.extra.user" 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /navigation/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | / 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoIbrahim15/Android-Kotlin-Modularization-MVI/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /dashboard/src/main/java/com/mi/dashboard/DashboardViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.mi.dashboard 2 | 3 | import androidx.lifecycle.ViewModel 4 | 5 | class DashboardViewModel : ViewModel() 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/mi/best_practice/koin/AppComponent.kt: -------------------------------------------------------------------------------- 1 | package com.mi.best_practice.koin 2 | 3 | import com.mi.dashboard.koin.featureDashboardModule 4 | 5 | val appModules = listOf(featureDashboardModule) 6 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.buildFileName = "build.gradle.kts" 2 | 3 | // this gradle version has an issue with settings kts file to read from constants 4 | include( 5 | ":app", 6 | ":navigation", 7 | ":dashboard" 8 | ) 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /dashboard/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id(GradlePluginId.ANDROID_APP) 3 | id(GradlePluginId.BASE_GRADLE_PLUGIN) 4 | } 5 | 6 | dependencies { 7 | implementation(project(ModulesDependency.NAVIGATION)) 8 | implementation(project(ModulesDependency.DASHBOARD)) 9 | } 10 | -------------------------------------------------------------------------------- /.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 | .cxx 15 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Feb 12 11:08:11 EET 2020 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-6.1.1-all.zip 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /dashboard/src/main/java/com/mi/dashboard/koin/FeatureDashboardModule.kt: -------------------------------------------------------------------------------- 1 | package com.mi.dashboard.koin 2 | 3 | import com.mi.dashboard.DashboardViewModel 4 | import org.koin.androidx.viewmodel.dsl.viewModel 5 | import org.koin.dsl.module 6 | 7 | val featureDashboardModule = module { 8 | viewModel { DashboardViewModel() } 9 | } 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android kotlin best practice include : 2 | Modularization 3 | Gradle Depedency managment 4 | Gradle rewritten in Kotlin DSL 5 | Custom Plugin(dependencies with no duplication) 6 | Static Code Analytics (KTLint-Detekt) 7 | KOIN service locator instead of Dagger (dependency injection) 8 | and more... 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /dashboard/src/test/java/com/mi/dashboard/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.mi.dashboard 2 | 3 | import org.junit.Assert.* 4 | import org.junit.Test 5 | 6 | /** 7 | * Example local unit test, which will execute on the development machine (host). 8 | * 9 | * See [testing documentation](http://d.android.com/tools/testing). 10 | */ 11 | class ExampleUnitTest { 12 | @Test 13 | fun addition_isCorrect() { 14 | assertEquals(4, 2 + 2) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /local.properties: -------------------------------------------------------------------------------- 1 | ## This file is automatically generated by Android Studio. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file should *NOT* be checked into Version Control Systems, 5 | # as it contains information specific to your local configuration. 6 | # 7 | # Location of the SDK. This is only used by Gradle. 8 | # For customization when using a Version Control System, please read the 9 | # header note. 10 | sdk.dir=/Users/mohamedibrahim/Library/Android/sdk -------------------------------------------------------------------------------- /dashboard/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | -------------------------------------------------------------------------------- /navigation/src/main/java/com/mi/navigation/Navigation.kt: -------------------------------------------------------------------------------- 1 | package com.mi.navigation 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | 6 | object Navigation { 7 | fun openDashboard(context: Context, userId: String) = 8 | internalIntent(context, "com.mi.navigation.dashboard.open") 9 | .putExtra(EXTRA_USER, userId) 10 | } 11 | 12 | private fun internalIntent(context: Context, action: String) = 13 | Intent(action).setPackage(context.packageName) 14 | -------------------------------------------------------------------------------- /dashboard/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id(GradlePluginId.ANDROID_LIB) 3 | id(GradlePluginId.BASE_GRADLE_PLUGIN) 4 | id(GradlePluginId.SAFE_ARGS) 5 | } 6 | 7 | dependencies { 8 | 9 | // support 10 | implementation(LibraryDependency.APPCOMPAT) 11 | implementation(LibraryDependency.CORE) 12 | implementation(LibraryDependency.MATERIAL) 13 | implementation(LibraryDependency.CONSTRAINT) 14 | implementation(LibraryDependency.NAVIGATION_FRAGMENT) 15 | implementation(LibraryDependency.NAVIGATION_UI) 16 | 17 | addTestDependencies() 18 | } 19 | -------------------------------------------------------------------------------- /dashboard/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | dashboard 3 | 4 | Settings 5 | 6 | First Fragment 7 | Second Fragment 8 | Next 9 | Previous 10 | 11 | Hello first fragment 12 | Hello second fragment. Arg: %1$s 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/mi/best_practice/App.kt: -------------------------------------------------------------------------------- 1 | package com.mi.best_practice 2 | 3 | import android.app.Application 4 | import com.mi.best_practice.koin.appModules 5 | import org.koin.android.ext.koin.androidContext 6 | import org.koin.android.ext.koin.androidLogger 7 | import org.koin.core.context.startKoin 8 | 9 | class App : Application() { 10 | 11 | override fun onCreate() { 12 | super.onCreate() 13 | configureDi() 14 | } 15 | 16 | private fun configureDi() { 17 | startKoin { 18 | androidLogger() 19 | androidContext(this@App) 20 | modules(appModules) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dashboard/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /dashboard/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 14 | 15 |