Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ plugins {
}

android {
compileSdkVersion 30
compileSdkVersion 33
buildToolsVersion "30.0.3"

defaultConfig {
applicationId "ru.otus.daggerhomework"
minSdkVersion 23
targetSdkVersion 30
targetSdkVersion 33
versionCode 1
versionName "1.0"

Expand All @@ -30,15 +30,21 @@ android {
}
kotlinOptions {
jvmTarget = '1.8'
freeCompilerArgs += [
"-Xjvm-default=all",
]
}
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'com.google.dagger:dagger:2.38.1'
kapt 'com.google.dagger:dagger-compiler:2.38.1'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.dagger:dagger:2.43.2'
kapt 'com.google.dagger:dagger-compiler:2.43.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
}
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".App"
android:theme="@style/Theme.DaggerHomework">
<activity android:name=".MainActivity">
<intent-filter>
Expand Down
9 changes: 8 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,12 @@ package ru.otus.daggerhomework

import android.app.Application

class App :Application() {
class App : Application() {

lateinit var appComponent: ApplicationComponent

override fun onCreate() {
super.onCreate()
appComponent = DaggerApplicationComponent.factory().create(this)
}
}
27 changes: 27 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/ApplicationComponent.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
package ru.otus.daggerhomework

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import javax.inject.Qualifier
import javax.inject.Scope
import javax.inject.Singleton

@Qualifier
annotation class QualifierAppContext

@Scope
annotation class FragmentScope

@Singleton
@Component
interface ApplicationComponent {

@QualifierAppContext
fun provideAppContext(): Context

@Component.Factory
interface AppComponentFactory {
fun create(
@QualifierAppContext
@BindsInstance
applicationContext: Context
): ApplicationComponent
}
}
4 changes: 2 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/ColorGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package ru.otus.daggerhomework

import android.graphics.Color
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import java.util.*
import javax.inject.Inject

interface ColorGenerator {

@ColorInt
fun generateColor(): Int
}

class ColorGeneratorImpl : ColorGenerator {
class ColorGeneratorImpl @Inject constructor() : ColorGenerator {

override fun generateColor(): Int {
val rnd = Random()
Expand Down
18 changes: 17 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/FragmentProducer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,37 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import javax.inject.Inject

class FragmentProducer : Fragment() {

@Inject
lateinit var viewModelFactory: ViewModelFactory
lateinit var viewModelProducer: ViewModelProducer

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DaggerFragmentProducerComponent.builder()
.mainActivityComponent((requireActivity() as MainActivity).activityComponent)
.build()
.inject(this)
viewModelProducer = ViewModelProvider(this, viewModelFactory)[ViewModelProducer::class.java]
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_a, container, true)
return inflater.inflate(R.layout.fragment_a, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.button).setOnClickListener {
//отправить результат через livedata в другой фрагмент
viewModelProducer.generateColor()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ru.otus.daggerhomework

import dagger.Component

@FragmentScope
@Component(dependencies = [MainActivityComponent::class], modules = [FragmentProducerModule::class])
interface FragmentProducerComponent {

fun inject(fragment: FragmentProducer)
}
18 changes: 18 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/FragmentProducerModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ru.otus.daggerhomework

import androidx.lifecycle.ViewModel
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap

@Module
interface FragmentProducerModule {

@Binds
@IntoMap
@ViewModelKey(ViewModelProducer::class)
fun viewModelProducer(viewModel: ViewModelProducer): ViewModel

@Binds
fun colorGeneratorBinds(generator: ColorGeneratorImpl): ColorGenerator
}
20 changes: 17 additions & 3 deletions app/src/main/java/ru/otus/daggerhomework/FragmentReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,42 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.annotation.ColorInt
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import javax.inject.Inject

class FragmentReceiver : Fragment() {

@Inject
lateinit var viewModelFactory: ViewModelFactory
lateinit var viewModelReceiver: ViewModelReceiver
private lateinit var frame: View

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DaggerFragmentReceiverComponent.builder()
.mainActivityComponent((requireActivity() as MainActivity).activityComponent)
.build()
.inject(this)
viewModelReceiver = ViewModelProvider(this, viewModelFactory)[ViewModelReceiver::class.java]
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_b, container, true)
return inflater.inflate(R.layout.fragment_b, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
frame = view.findViewById(R.id.frame)
viewModelReceiver.observeColors { populateColor(it) }
}

fun populateColor(@ColorInt color: Int) {
private fun populateColor(@ColorInt color: Int) {
frame.setBackgroundColor(color)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ru.otus.daggerhomework

import dagger.Component

@FragmentScope
@Component(dependencies = [MainActivityComponent::class], modules = [FragmentReceiverModule::class])
interface FragmentReceiverComponent {

fun inject(fragment: FragmentReceiver)
}
15 changes: 15 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/FragmentReceiverModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.otus.daggerhomework

import androidx.lifecycle.ViewModel
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap

@Module
interface FragmentReceiverModule {

@Binds
@IntoMap
@ViewModelKey(ViewModelReceiver::class)
fun viewModelReceiver(viewModel: ViewModelReceiver): ViewModel
}
15 changes: 15 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,23 @@ import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

lateinit var activityComponent: MainActivityComponent

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

activityComponent = DaggerMainActivityComponent
.factory()
.create(this, (application as App).appComponent)
.also { activityComponent = it }

setContentView(R.layout.activity_main)

supportFragmentManager
.beginTransaction()
.add(R.id.container_view, FragmentReceiver())
.add(R.id.container_view, FragmentProducer())
.commit()
}
}
30 changes: 30 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/MainActivityComponent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ru.otus.daggerhomework

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Scope

@Scope
annotation class ActivityScope

@ActivityScope
@Component(dependencies = [ApplicationComponent::class], modules = [MainActivityModule::class])
interface MainActivityComponent {

@QualifierAppContext
fun appContextProvide(): Context

fun activityContextProvide(): Context

fun stateFlowProvide(): MutableStateFlow<Int>

@Component.Factory
interface MainActivityComponentFactory {
fun create(
@BindsInstance activityContext: Context,
applicationComponent: ApplicationComponent
): MainActivityComponent
}
}
13 changes: 13 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/MainActivityModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ru.otus.daggerhomework

import dagger.Module
import dagger.Provides
import kotlinx.coroutines.flow.MutableStateFlow

@Module
class MainActivityModule {

@ActivityScope
@Provides
fun stateObserver(): MutableStateFlow<Int> = MutableStateFlow(0)
}
20 changes: 20 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ru.otus.daggerhomework

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import dagger.MapKey
import javax.inject.Inject
import javax.inject.Provider
import kotlin.reflect.KClass

@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)

class ViewModelFactory @Inject constructor(
private val viewModels: MutableMap<Class<out ViewModel>,
@JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {

override fun <T : ViewModel> create(modelClass: Class<T>): T =
viewModels[modelClass]?.get() as T
}
7 changes: 5 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelProducer.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package ru.otus.daggerhomework

import android.app.Activity
import android.content.Context
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import java.lang.RuntimeException
import javax.inject.Inject

class ViewModelProducer(
class ViewModelProducer @Inject constructor(
private val stateFlow: MutableStateFlow<Int>,
private val colorGenerator: ColorGenerator,
private val context: Context
) : ViewModel() {

fun generateColor() {
if (context !is FragmentActivity) throw RuntimeException("Здесь нужен контекст активити")
stateFlow.value = colorGenerator.generateColor()
Toast.makeText(context, "Color sent", Toast.LENGTH_LONG).show()
}
}
Loading