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
7 changes: 5 additions & 2 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 31
buildToolsVersion "30.0.3"

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

Expand Down Expand Up @@ -40,5 +40,8 @@ dependencies {
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'com.google.dagger:dagger:2.38.1'
implementation 'androidx.fragment:fragment-ktx:1.4.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
kapt 'com.google.dagger:dagger-compiler:2.38.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1'
}
5 changes: 3 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.otus.daggerhomework">

<application
<application android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DaggerHomework">
<activity android:name=".MainActivity">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
10 changes: 9 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,13 @@ package ru.otus.daggerhomework

import android.app.Application

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

lateinit var applicationComponent: ApplicationComponent

override fun onCreate() {
super.onCreate()

applicationComponent = DaggerApplicationComponent.factory().create(this)
}
}
18 changes: 18 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,22 @@
package ru.otus.daggerhomework

import android.content.Context
import dagger.BindsInstance
import dagger.Component

@Component
interface ApplicationComponent {

@ApplicationContextQualifier
fun provideApplicationContext(): Context

@Component.Factory
interface ApplicationComponentFactory {

fun create(
@ApplicationContextQualifier
@BindsInstance
applicationContext: Context
): ApplicationComponent
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/Color.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ru.otus.daggerhomework

@JvmInline
value class Color constructor(val color: Int)
3 changes: 2 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/ColorGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ 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
36 changes: 36 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/DaggerAnnotations.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ru.otus.daggerhomework

import androidx.lifecycle.ViewModel
import dagger.MapKey
import javax.inject.Qualifier
import javax.inject.Scope
import kotlin.reflect.KClass

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class ApplicationScope

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class ActivityScope

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class FragmentScope

@MapKey
@Retention(AnnotationRetention.RUNTIME)
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER
)
annotation class ViewModelKey(val value: KClass<out ViewModel>)

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class ActivityContextQualifier

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class ApplicationContextQualifier
24 changes: 23 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/FragmentProducer.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,48 @@
package ru.otus.daggerhomework

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
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 vm: ViewModelProducer

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)

vm = ViewModelProvider(this, viewModelFactory)[ViewModelProducer::class.java]

view.findViewById<Button>(R.id.button).setOnClickListener {
vm.generateColor()
//отправить результат через livedata в другой фрагмент
}
}

override fun onAttach(context: Context) {
super.onAttach(context)

DaggerFragmentProducerComponent
.builder()
.mainActivityComponent((activity as MainActivity).component)
.build()
.inject(this)
}
}
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)
}
19 changes: 19 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,19 @@
package ru.otus.daggerhomework

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

@Module
interface FragmentProducerModule {

@Binds
@FragmentScope
fun bindsColorGenerator(impl: ColorGeneratorImpl): ColorGenerator

@Binds
@IntoMap
@ViewModelKey(ViewModelProducer::class)
fun bindsViewModelProducer(viewModelProducer: ViewModelProducer): ViewModel
}
39 changes: 36 additions & 3 deletions app/src/main/java/ru/otus/daggerhomework/FragmentReceiver.kt
Original file line number Diff line number Diff line change
@@ -1,31 +1,64 @@
package ru.otus.daggerhomework

import android.content.Context
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.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.launch
import javax.inject.Inject

class FragmentReceiver : Fragment() {

@Inject
lateinit var viewModelFactory: ViewModelFactory

lateinit var vm: ViewModelReceiver

private lateinit var frame: View

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)

vm = ViewModelProvider(this, viewModelFactory)[ViewModelReceiver::class.java]
vm.observeColors()

viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
vm.colorFlow.collect {
populateColor(it.color)
}
}
}
}

override fun onAttach(context: Context) {
super.onAttach(context)

DaggerFragmentReceiverComponent
.builder()
.mainActivityComponent((activity as MainActivity).component)
.applicationComponent((activity?.application as App).applicationComponent)
.build()
.inject(this)
}

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,9 @@
package ru.otus.daggerhomework

import dagger.Component

@FragmentScope
@Component(dependencies = [ApplicationComponent::class, 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 bindsReceiverViewModel(viewModelReceiver: ViewModelReceiver): ViewModel
}
13 changes: 12 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
package ru.otus.daggerhomework

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

lateinit var component: MainActivityComponent

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

component = DaggerMainActivityComponent
.factory()
.create(
this,
(application as App).applicationComponent,
)

setContentView(R.layout.activity_main)
}
}
31 changes: 31 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,31 @@
package ru.otus.daggerhomework

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

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

@ActivityContextQualifier
fun provideActivityContext(): Context

fun provideColorStateFlow(): MutableStateFlow<Color>

@Component.Factory
interface MainActivityComponentFactory {

fun create(
@BindsInstance
@ActivityContextQualifier
activityContext: Context,
mainActivityComponent: ApplicationComponent
): MainActivityComponent
}
}
14 changes: 14 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,14 @@
package ru.otus.daggerhomework

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

@Module
class MainActivityModule {

@ActivityScope
@Provides
fun providesColorStateFlow(): MutableStateFlow<Color> = MutableStateFlow(Color(0))
}
Loading