From 3dc21165165b2edbeeb37ba7acfb1edbe1e1b999 Mon Sep 17 00:00:00 2001 From: Evgeny Dubravin Date: Fri, 15 Mar 2024 17:16:41 +0700 Subject: [PATCH 01/11] set submodules --- .gitmodules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitmodules b/.gitmodules index 2346927..899bad4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ +[submodule "Template-common"] + path = Template-common + url = git@github.com:TouchInstinct/Template-common.git [submodule "RoboSwag"] path = RoboSwag url = https://git.svc.touchin.ru/TouchInstinct/RoboSwag.git -- 2.40.1 From 1c0b7125e894a65235cf880c27ea9082f812b5a2 Mon Sep 17 00:00:00 2001 From: Evgeny Dubravin Date: Fri, 22 Mar 2024 20:25:18 +0700 Subject: [PATCH 02/11] =?UTF-8?q?feature=20TI-186:=20[Android]=20=D0=9D?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B5=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- buildSrc/src/main/kotlin/VersionCatalogLibraries.kt | 10 ++++++++++ buildSrc/src/main/kotlin/VersionCatalogVersions.kt | 7 +++++++ buildSrc/src/main/kotlin/plugins/AndroidAppPlugin.kt | 3 +++ gradle/libs.versions.toml | 3 +++ 4 files changed, 23 insertions(+) create mode 100644 buildSrc/src/main/kotlin/VersionCatalogLibraries.kt create mode 100644 buildSrc/src/main/kotlin/VersionCatalogVersions.kt diff --git a/buildSrc/src/main/kotlin/VersionCatalogLibraries.kt b/buildSrc/src/main/kotlin/VersionCatalogLibraries.kt new file mode 100644 index 0000000..28aea6c --- /dev/null +++ b/buildSrc/src/main/kotlin/VersionCatalogLibraries.kt @@ -0,0 +1,10 @@ +import org.gradle.api.artifacts.MinimalExternalModuleDependency +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.provider.Provider + +internal val VersionCatalog.stdlib: Provider + get() = getLibrary("stdLib") + + +private fun VersionCatalog.getLibrary(library: String) = findLibrary(library).get() + diff --git a/buildSrc/src/main/kotlin/VersionCatalogVersions.kt b/buildSrc/src/main/kotlin/VersionCatalogVersions.kt new file mode 100644 index 0000000..10b179f --- /dev/null +++ b/buildSrc/src/main/kotlin/VersionCatalogVersions.kt @@ -0,0 +1,7 @@ +import org.gradle.api.artifacts.VersionCatalog + +val VersionCatalog.sdkCompile: String + get() = findVersion("compileSdk").get().requiredVersion + +val VersionCatalog.sdkMin: String + get() = findVersion("minSdk").get().requiredVersion diff --git a/buildSrc/src/main/kotlin/plugins/AndroidAppPlugin.kt b/buildSrc/src/main/kotlin/plugins/AndroidAppPlugin.kt index 7c2d004..5cb825e 100644 --- a/buildSrc/src/main/kotlin/plugins/AndroidAppPlugin.kt +++ b/buildSrc/src/main/kotlin/plugins/AndroidAppPlugin.kt @@ -2,6 +2,9 @@ package plugins import versioncatalog.androidApplicationPlugin import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.getByType class AndroidAppPlugin : BaseAndroidPlugin() { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index def2a24..bd969af 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -150,6 +150,9 @@ groupie = { group = "com.github.lisawray.groupie", name = "groupie", version.ref groupie-viewbinding = { group = "com.github.lisawray.groupie", name = "groupie-viewbinding", version.ref = "groupie" } javapoet = { module = "com.squareup:javapoet", version = "javapoet" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } +espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } -- 2.40.1 From 367d2f613347cedb78f33da843b3a3af5faccc4a Mon Sep 17 00:00:00 2001 From: Evgeny Dubravin Date: Sat, 23 Mar 2024 00:15:44 +0700 Subject: [PATCH 03/11] =?UTF-8?q?feature=20TI-187:=20[Android]=20=D0=9D?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/libs.versions.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bd969af..94d9411 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -150,6 +150,7 @@ groupie = { group = "com.github.lisawray.groupie", name = "groupie", version.ref groupie-viewbinding = { group = "com.github.lisawray.groupie", name = "groupie-viewbinding", version.ref = "groupie" } javapoet = { module = "com.squareup:javapoet", version = "javapoet" } + junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" } -- 2.40.1 From ff33b099ad9934f8e80c8165b357f83f8a57d5d3 Mon Sep 17 00:00:00 2001 From: Evgeny Dubravin Date: Sat, 23 Mar 2024 00:16:48 +0700 Subject: [PATCH 04/11] =?UTF-8?q?feature=20TI-188:=20[Android]=20=D0=9D?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=20flavor,=20bu?= =?UTF-8?q?ildType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- buildSrc/src/main/kotlin/VersionCatalogLibraries.kt | 4 ---- buildSrc/src/main/kotlin/VersionCatalogVersions.kt | 12 ++++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/buildSrc/src/main/kotlin/VersionCatalogLibraries.kt b/buildSrc/src/main/kotlin/VersionCatalogLibraries.kt index 28aea6c..faaf8dd 100644 --- a/buildSrc/src/main/kotlin/VersionCatalogLibraries.kt +++ b/buildSrc/src/main/kotlin/VersionCatalogLibraries.kt @@ -2,9 +2,5 @@ import org.gradle.api.artifacts.MinimalExternalModuleDependency import org.gradle.api.artifacts.VersionCatalog import org.gradle.api.provider.Provider -internal val VersionCatalog.stdlib: Provider - get() = getLibrary("stdLib") - - private fun VersionCatalog.getLibrary(library: String) = findLibrary(library).get() diff --git a/buildSrc/src/main/kotlin/VersionCatalogVersions.kt b/buildSrc/src/main/kotlin/VersionCatalogVersions.kt index 10b179f..e556827 100644 --- a/buildSrc/src/main/kotlin/VersionCatalogVersions.kt +++ b/buildSrc/src/main/kotlin/VersionCatalogVersions.kt @@ -5,3 +5,15 @@ val VersionCatalog.sdkCompile: String val VersionCatalog.sdkMin: String get() = findVersion("minSdk").get().requiredVersion + +val VersionCatalog.sdkTarget: String + get() = findVersion("targetSdk").get().requiredVersion + +val VersionCatalog.jvmBytecode: String + get() = findVersion("jvmBytecode").get().requiredVersion + +val VersionCatalog.versionCode: String + get() = findVersion("versionCode").get().requiredVersion + +val VersionCatalog.versionName: String + get() = findVersion("versionName").get().requiredVersion -- 2.40.1 From cea58fb43f40ed6baab44ddb2dfe5efa7581688e Mon Sep 17 00:00:00 2001 From: Evgeny Dubravin Date: Mon, 25 Mar 2024 18:11:23 +0700 Subject: [PATCH 05/11] set common-template submodule --- .gitmodules | 3 --- app/src/main/res/values/strings.xml | 0 2 files changed, 3 deletions(-) create mode 100644 app/src/main/res/values/strings.xml diff --git a/.gitmodules b/.gitmodules index 899bad4..2346927 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "Template-common"] - path = Template-common - url = git@github.com:TouchInstinct/Template-common.git [submodule "RoboSwag"] path = RoboSwag url = https://git.svc.touchin.ru/TouchInstinct/RoboSwag.git diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..e69de29 -- 2.40.1 From c2ea82179110f90a3b63bf982846b968f047e6e5 Mon Sep 17 00:00:00 2001 From: Evgeny Dubravin Date: Thu, 28 Mar 2024 17:10:25 +0700 Subject: [PATCH 06/11] =?UTF-8?q?feature=20TI-193:=20[Android]=20=D0=A0?= =?UTF-8?q?=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20?= =?UTF-8?q?ViewModel=20Factory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/ru/touchin/template/App.kt | 15 +++++++++- .../ru/touchin/template/SingleViewModel.kt | 6 ++++ .../template/base/activity/BaseActivity.kt | 12 ++++++++ .../template/base/fragment/BaseFragment.kt | 12 ++++++++ .../ru/touchin/template/di/AppComponent.kt | 30 +++++++++++++++++++ .../main/java/ru/touchin/template/di/DI.kt | 16 ++++++++++ .../touchin/template/di/SharedComponentExt.kt | 17 +++++++++++ .../template/di/SharedComponentProvider.kt | 15 ++++++++++ .../touchin/template/di/modules/AppModule.kt | 11 +++++++ .../template/di/modules/NetworkModule.kt | 7 +++++ .../template/di/modules/RepositoryModule.kt | 7 +++++ .../template/di/modules/ViewModelModule.kt | 22 ++++++++++++++ .../template/di/viewmodel/ViewModelFactory.kt | 17 +++++++++++ .../template/di/viewmodel/ViewModelKey.kt | 9 ++++++ common-template | 1 + 15 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/ru/touchin/template/SingleViewModel.kt create mode 100644 app/src/main/java/ru/touchin/template/base/activity/BaseActivity.kt create mode 100644 app/src/main/java/ru/touchin/template/base/fragment/BaseFragment.kt create mode 100644 app/src/main/java/ru/touchin/template/di/AppComponent.kt create mode 100644 app/src/main/java/ru/touchin/template/di/DI.kt create mode 100644 app/src/main/java/ru/touchin/template/di/SharedComponentExt.kt create mode 100644 app/src/main/java/ru/touchin/template/di/SharedComponentProvider.kt create mode 100644 app/src/main/java/ru/touchin/template/di/modules/AppModule.kt create mode 100644 app/src/main/java/ru/touchin/template/di/modules/NetworkModule.kt create mode 100644 app/src/main/java/ru/touchin/template/di/modules/RepositoryModule.kt create mode 100644 app/src/main/java/ru/touchin/template/di/modules/ViewModelModule.kt create mode 100644 app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelFactory.kt create mode 100644 app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelKey.kt create mode 160000 common-template diff --git a/app/src/main/java/ru/touchin/template/App.kt b/app/src/main/java/ru/touchin/template/App.kt index c6ffdc1..0048de1 100644 --- a/app/src/main/java/ru/touchin/template/App.kt +++ b/app/src/main/java/ru/touchin/template/App.kt @@ -1,5 +1,18 @@ package ru.touchin.template import android.app.Application +import ru.touchin.template.di.DI +import ru.touchin.template.di.SharedComponent +import ru.touchin.template.di.SharedComponentProvider -class App : Application() +class App : Application(), SharedComponentProvider { + + override fun onCreate() { + super.onCreate() + + DI.init(applicationContext) + DI.getComponent().inject(this) + } + + override fun getModule(): SharedComponent = DI.getComponent() +} diff --git a/app/src/main/java/ru/touchin/template/SingleViewModel.kt b/app/src/main/java/ru/touchin/template/SingleViewModel.kt new file mode 100644 index 0000000..15b24f0 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/SingleViewModel.kt @@ -0,0 +1,6 @@ +package ru.touchin.template + +import androidx.lifecycle.ViewModel +import javax.inject.Inject + +class SingleViewModel @Inject constructor() : ViewModel() \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/base/activity/BaseActivity.kt b/app/src/main/java/ru/touchin/template/base/activity/BaseActivity.kt new file mode 100644 index 0000000..df11275 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/base/activity/BaseActivity.kt @@ -0,0 +1,12 @@ +package ru.touchin.template.base.activity + +import androidx.appcompat.app.AppCompatActivity +import ru.touchin.template.di.SharedComponent +import ru.touchin.template.di.getSharedModule + +class BaseActivity : AppCompatActivity() { + + protected val viewModelFactory by lazy { getSharedComponent().viewModelFactory() } + + protected fun getSharedComponent(): SharedComponent = getSharedModule() +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/base/fragment/BaseFragment.kt b/app/src/main/java/ru/touchin/template/base/fragment/BaseFragment.kt new file mode 100644 index 0000000..c9c3c8e --- /dev/null +++ b/app/src/main/java/ru/touchin/template/base/fragment/BaseFragment.kt @@ -0,0 +1,12 @@ +package ru.touchin.template.base.fragment + +import androidx.fragment.app.Fragment +import ru.touchin.template.di.SharedComponent +import ru.touchin.template.di.getSharedModule + +class BaseFragment : Fragment() { + + protected val viewModelFactory by lazy { getSharedComponent().viewModelFactory() } + + protected fun getSharedComponent(): SharedComponent = getSharedModule() +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/AppComponent.kt b/app/src/main/java/ru/touchin/template/di/AppComponent.kt new file mode 100644 index 0000000..f4b7320 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/AppComponent.kt @@ -0,0 +1,30 @@ +package ru.touchin.template.di + +import android.content.Context +import dagger.BindsInstance +import dagger.Component +import javax.inject.Singleton +import ru.touchin.template.App +import ru.touchin.template.di.modules.AppModule +import ru.touchin.template.di.modules.ViewModelModule + +@Component( + modules = [ + AppModule::class, + ViewModelModule::class + ] +) +@Singleton +interface AppComponent : SharedComponent { + + @Component.Builder + interface Builder { + + @BindsInstance + fun appContext(appContext: Context): Builder + + fun build(): AppComponent + } + + fun inject(entry: App) +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/DI.kt b/app/src/main/java/ru/touchin/template/di/DI.kt new file mode 100644 index 0000000..626c007 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/DI.kt @@ -0,0 +1,16 @@ +package ru.touchin.template.di + +import android.content.Context + +object DI { + + private lateinit var appComponent: AppComponent + + fun init(context: Context) { + appComponent = DaggerAppComponent.builder() + .appContext(context) + .build() + } + + fun getComponent(): AppComponent = appComponent +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/SharedComponentExt.kt b/app/src/main/java/ru/touchin/template/di/SharedComponentExt.kt new file mode 100644 index 0000000..36993ee --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/SharedComponentExt.kt @@ -0,0 +1,17 @@ +package ru.touchin.template.di + +import android.app.Activity +import android.content.Context +import androidx.fragment.app.Fragment + +fun Context.getSharedModule(): SharedComponent { + return (applicationContext as SharedComponentProvider).getModule() +} + +fun Activity.getSharedModule(): SharedComponent { + return (applicationContext as SharedComponentProvider).getModule() +} + +fun Fragment.getSharedModule(): SharedComponent { + return requireContext().getSharedModule() +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/SharedComponentProvider.kt b/app/src/main/java/ru/touchin/template/di/SharedComponentProvider.kt new file mode 100644 index 0000000..0ee19ab --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/SharedComponentProvider.kt @@ -0,0 +1,15 @@ +package ru.touchin.template.di + +import dagger.Module +import ru.touchin.template.di.viewmodel.ViewModelFactory + +interface SharedComponent { + fun viewModelFactory(): ViewModelFactory +} + +@Module +class SharedModule + +interface SharedComponentProvider { + fun getModule(): SharedComponent +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/modules/AppModule.kt b/app/src/main/java/ru/touchin/template/di/modules/AppModule.kt new file mode 100644 index 0000000..0943510 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/modules/AppModule.kt @@ -0,0 +1,11 @@ +package ru.touchin.template.di.modules + +import dagger.Module + +@Module( + includes = [ + RepositoryModule::class, + NetworkModule::class + ] +) +class AppModule \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/modules/NetworkModule.kt b/app/src/main/java/ru/touchin/template/di/modules/NetworkModule.kt new file mode 100644 index 0000000..8c14718 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/modules/NetworkModule.kt @@ -0,0 +1,7 @@ +package ru.touchin.template.di.modules + +import dagger.Module + +@Module +class NetworkModule { +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/modules/RepositoryModule.kt b/app/src/main/java/ru/touchin/template/di/modules/RepositoryModule.kt new file mode 100644 index 0000000..f995563 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/modules/RepositoryModule.kt @@ -0,0 +1,7 @@ +package ru.touchin.template.di.modules + +import dagger.Module + +@Module +class RepositoryModule { +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/modules/ViewModelModule.kt b/app/src/main/java/ru/touchin/template/di/modules/ViewModelModule.kt new file mode 100644 index 0000000..9331a01 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/modules/ViewModelModule.kt @@ -0,0 +1,22 @@ +package ru.touchin.template.di.modules + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import ru.touchin.template.SingleViewModel +import ru.touchin.template.di.viewmodel.ViewModelFactory +import ru.touchin.template.di.viewmodel.ViewModelKey + +@Module +interface ViewModelModule { + + @Binds + fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory + + @Binds + @IntoMap + @ViewModelKey(SingleViewModel::class) + fun bindsSingleViewModel(viewModel: SingleViewModel): ViewModel +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelFactory.kt b/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelFactory.kt new file mode 100644 index 0000000..297984b --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelFactory.kt @@ -0,0 +1,17 @@ +package ru.touchin.template.di.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import javax.inject.Inject +import javax.inject.Provider + +class ViewModelFactory @Inject constructor( + private val viewModels: MutableMap, Provider> +) : ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun create(modelClass: Class): T { + val viewModel = viewModels[modelClass]?.get() + return viewModel as T + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelKey.kt b/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelKey.kt new file mode 100644 index 0000000..1f76f60 --- /dev/null +++ b/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelKey.kt @@ -0,0 +1,9 @@ +package ru.touchin.template.di.viewmodel + +import androidx.lifecycle.ViewModel +import dagger.MapKey +import kotlin.reflect.KClass + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) +@MapKey +annotation class ViewModelKey(val value: KClass) \ No newline at end of file diff --git a/common-template b/common-template new file mode 160000 index 0000000..d6f303b --- /dev/null +++ b/common-template @@ -0,0 +1 @@ +Subproject commit d6f303bf879a2da1706cfdacaf2bbe0c326044bd -- 2.40.1 From a81a66bdb9841720cabd3114f91cbb19c018e21e Mon Sep 17 00:00:00 2001 From: Evgeny Dubravin Date: Fri, 29 Mar 2024 22:36:19 +0700 Subject: [PATCH 07/11] feature TI-194: [Android] DI --- app/src/main/AndroidManifest.xml | 6 ++--- .../ru/touchin/template/SingleActivity.kt | 5 ---- .../template/base/activity/BaseActivity.kt | 7 ++++- .../template/base/fragment/BaseFragment.kt | 5 +++- .../template/di/SharedComponentProvider.kt | 2 ++ .../template/di/modules/ViewModelModule.kt | 9 ++++++- .../template/di/viewmodel/ViewModelFactory.kt | 27 +++++++++++++++++++ app/src/main/res/layout/activity_main.xml | 24 ++++++++++++++--- app/src/main/res/layout/fragment_first.xml | 27 +++++++++++++++++++ app/src/main/res/layout/fragment_second.xml | 27 +++++++++++++++++++ 10 files changed, 124 insertions(+), 15 deletions(-) delete mode 100644 app/src/main/java/ru/touchin/template/SingleActivity.kt create mode 100644 app/src/main/res/layout/fragment_first.xml create mode 100644 app/src/main/res/layout/fragment_second.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 498225a..0f6717f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,12 +11,12 @@ android:label="@string/common_app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="false" - tools:ignore="GoogleAppIndexingWarning"> + tools:ignore="GoogleAppIndexingWarning" + android:theme="@style/AppTheme"> diff --git a/app/src/main/java/ru/touchin/template/SingleActivity.kt b/app/src/main/java/ru/touchin/template/SingleActivity.kt deleted file mode 100644 index e71c1db..0000000 --- a/app/src/main/java/ru/touchin/template/SingleActivity.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.touchin.template - -import androidx.appcompat.app.AppCompatActivity - -class SingleActivity : AppCompatActivity() diff --git a/app/src/main/java/ru/touchin/template/base/activity/BaseActivity.kt b/app/src/main/java/ru/touchin/template/base/activity/BaseActivity.kt index df11275..0100cf3 100644 --- a/app/src/main/java/ru/touchin/template/base/activity/BaseActivity.kt +++ b/app/src/main/java/ru/touchin/template/base/activity/BaseActivity.kt @@ -1,12 +1,17 @@ package ru.touchin.template.base.activity import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.ViewModel import ru.touchin.template.di.SharedComponent import ru.touchin.template.di.getSharedModule -class BaseActivity : AppCompatActivity() { +abstract class BaseActivity : AppCompatActivity() { + + protected val viewModel: T by lazy { createViewModelLazy().value } protected val viewModelFactory by lazy { getSharedComponent().viewModelFactory() } + abstract fun createViewModelLazy(): Lazy + protected fun getSharedComponent(): SharedComponent = getSharedModule() } \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/base/fragment/BaseFragment.kt b/app/src/main/java/ru/touchin/template/base/fragment/BaseFragment.kt index c9c3c8e..7125d9e 100644 --- a/app/src/main/java/ru/touchin/template/base/fragment/BaseFragment.kt +++ b/app/src/main/java/ru/touchin/template/base/fragment/BaseFragment.kt @@ -1,12 +1,15 @@ package ru.touchin.template.base.fragment import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModel import ru.touchin.template.di.SharedComponent import ru.touchin.template.di.getSharedModule -class BaseFragment : Fragment() { +abstract class BaseFragment : Fragment() { protected val viewModelFactory by lazy { getSharedComponent().viewModelFactory() } + protected abstract fun createViewModelLazy(): Lazy + protected fun getSharedComponent(): SharedComponent = getSharedModule() } \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/SharedComponentProvider.kt b/app/src/main/java/ru/touchin/template/di/SharedComponentProvider.kt index 0ee19ab..771a420 100644 --- a/app/src/main/java/ru/touchin/template/di/SharedComponentProvider.kt +++ b/app/src/main/java/ru/touchin/template/di/SharedComponentProvider.kt @@ -2,9 +2,11 @@ package ru.touchin.template.di import dagger.Module import ru.touchin.template.di.viewmodel.ViewModelFactory +import ru.touchin.template.feature.second.SecondViewModel interface SharedComponent { fun viewModelFactory(): ViewModelFactory + fun secondScreenViewModelFactory(): SecondViewModel.Factory } @Module diff --git a/app/src/main/java/ru/touchin/template/di/modules/ViewModelModule.kt b/app/src/main/java/ru/touchin/template/di/modules/ViewModelModule.kt index 9331a01..781d5ad 100644 --- a/app/src/main/java/ru/touchin/template/di/modules/ViewModelModule.kt +++ b/app/src/main/java/ru/touchin/template/di/modules/ViewModelModule.kt @@ -5,9 +5,10 @@ import androidx.lifecycle.ViewModelProvider import dagger.Binds import dagger.Module import dagger.multibindings.IntoMap -import ru.touchin.template.SingleViewModel import ru.touchin.template.di.viewmodel.ViewModelFactory import ru.touchin.template.di.viewmodel.ViewModelKey +import ru.touchin.template.feature.SingleViewModel +import ru.touchin.template.feature.first.FirstViewModel @Module interface ViewModelModule { @@ -19,4 +20,10 @@ interface ViewModelModule { @IntoMap @ViewModelKey(SingleViewModel::class) fun bindsSingleViewModel(viewModel: SingleViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(FirstViewModel::class) + fun bindsFirstViewModel(viewModel: FirstViewModel): ViewModel + } \ No newline at end of file diff --git a/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelFactory.kt b/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelFactory.kt index 297984b..699e68c 100644 --- a/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelFactory.kt +++ b/app/src/main/java/ru/touchin/template/di/viewmodel/ViewModelFactory.kt @@ -1,7 +1,13 @@ package ru.touchin.template.di.viewmodel +import android.os.Bundle +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.AbstractSavedStateViewModelFactory +import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import androidx.savedstate.SavedStateRegistryOwner import javax.inject.Inject import javax.inject.Provider @@ -14,4 +20,25 @@ class ViewModelFactory @Inject constructor( val viewModel = viewModels[modelClass]?.get() return viewModel as T } +} + +inline fun Fragment.assistedViewModel( + crossinline creator: (SavedStateHandle) -> VM, +): Lazy = viewModels { createAbstractSavedStateViewModelFactory(arguments, creator) } + +inline fun SavedStateRegistryOwner.createAbstractSavedStateViewModelFactory( + arguments: Bundle? = Bundle(), + crossinline creator: (SavedStateHandle) -> T, +): ViewModelProvider.Factory { + return object : AbstractSavedStateViewModelFactory( + owner = this@createAbstractSavedStateViewModelFactory, + defaultArgs = arguments, + ) { + @Suppress("UNCHECKED_CAST") + override fun create( + key: String, + modelClass: Class, + handle: SavedStateHandle, + ): T = creator(handle) as T + } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index a066a0d..9de21c1 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,6 +1,22 @@ - - + android:layout_height="match_parent" + android:background="@color/biometric_error_color"> + + + + + + diff --git a/app/src/main/res/layout/fragment_first.xml b/app/src/main/res/layout/fragment_first.xml new file mode 100644 index 0000000..a36f0ea --- /dev/null +++ b/app/src/main/res/layout/fragment_first.xml @@ -0,0 +1,27 @@ + + + + + +