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
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'com.google.dagger:dagger:2.42'
kapt 'com.google.dagger:dagger-compiler:2.42'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
}
8 changes: 5 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.otus.daggerhomework">

<application
android:allowBackup="true"
android:name=".App"
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
14 changes: 13 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/App.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
package ru.otus.daggerhomework

import android.app.Application
import ru.otus.daggerhomework.di.ApplicationComponent
import ru.otus.daggerhomework.di.DaggerApplicationComponent


class App : Application() {

lateinit var appComponent: ApplicationComponent
private set

override fun onCreate() {
super.onCreate()
appComponent = DaggerApplicationComponent.factory().create(this)
}

class App :Application() {
}

This file was deleted.

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
29 changes: 25 additions & 4 deletions app/src/main/java/ru/otus/daggerhomework/FragmentProducer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,42 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import ru.otus.daggerhomework.di.DaggerFragmentProducerComponent
import ru.otus.daggerhomework.di.FragmentProducerComponent
import javax.inject.Inject

class FragmentProducer : Fragment() {

@Inject
lateinit var viewModelFactory: ViewModelProducer.Factory

private val viewModelProducer by lazy {
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 onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val fragmentProducerComponent = DaggerFragmentProducerComponent.factory()
.create((requireActivity() as MainActivity).mainActivityComponent)
fragmentProducerComponent.inject(this)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.button).setOnClickListener {
//отправить результат через livedata в другой фрагмент
}

view.findViewById<Button>(R.id.button)
.setOnClickListener {
viewModelProducer.generateColor()
}
}
}
27 changes: 25 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/FragmentReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,48 @@ 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 androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import ru.otus.daggerhomework.di.DaggerFragmentReceiverComponent
import ru.otus.daggerhomework.di.FragmentReceiverComponent
import javax.inject.Inject

class FragmentReceiver : Fragment() {

@Inject
lateinit var viewModelFactory: ViewModelReceiver.Factory

private val viewModelReceiver by lazy {
ViewModelProvider(this, viewModelFactory)[ViewModelReceiver::class.java]
}

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 onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val fragmentReceiverComponent = DaggerFragmentReceiverComponent.factory().create((requireActivity() as MainActivity).mainActivityComponent)
fragmentReceiverComponent.inject(this)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

frame = view.findViewById(R.id.frame)
viewModelReceiver.observeColors().onEach {
populateColor(it)
}.launchIn(lifecycleScope)
}

fun populateColor(@ColorInt color: Int) {
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,23 @@ package ru.otus.daggerhomework

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import ru.otus.daggerhomework.di.DaggerMainActivityComponent
import ru.otus.daggerhomework.di.MainActivityComponent

class MainActivity : AppCompatActivity() {

lateinit var mainActivityComponent: MainActivityComponent
private set

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainActivityComponent = DaggerMainActivityComponent.factory().create(this, (application as App).appComponent)

supportFragmentManager
.beginTransaction()
.add(R.id.fragment_a, FragmentReceiver())
.add(R.id.fragment_b, FragmentProducer())
.commit()
}
}
25 changes: 23 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelProducer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,35 @@ package ru.otus.daggerhomework
import android.content.Context
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject

class ViewModelProducer(
private val colorGenerator: ColorGenerator,
private val context: Context
) {
private val context: Context,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь будет утечка контекста тк андродовская ViewModel живет дольше чем активити. Убери суперкласс

val stateFlow: MutableStateFlow<Int>
) : ViewModel() {

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


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

override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ViewModelProducer::class.java))
return ViewModelProducer(colorGenerator, context, stateFlow) as T
else throw IllegalArgumentException()
}
}
}
26 changes: 23 additions & 3 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,33 @@ package ru.otus.daggerhomework
import android.app.Application
import android.content.Context
import android.widget.Toast
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import kotlinx.coroutines.flow.StateFlow
import ru.otus.daggerhomework.di.ApplicationContext
import javax.inject.Inject

class ViewModelReceiver(
private val context: Context
) {
private val context: Context,
private val stateFlow: StateFlow<Int>
): ViewModel() {

fun observeColors() {
fun observeColors() : StateFlow<Int>{
if (context !is Application) throw RuntimeException("Здесь нужен контекст апликейшена")
Toast.makeText(context, "Color received", Toast.LENGTH_LONG).show()
return stateFlow
}

class Factory @Inject constructor(
@ApplicationContext val context: Context,
val stateFlow: StateFlow<Int>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ViewModelReceiver::class.java)) {
return ViewModelReceiver(context, stateFlow) as T
} else {
throw IllegalArgumentException("Unknown ViewModel class")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ru.otus.daggerhomework.di

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


@Component
@Singleton
interface ApplicationComponent {

@ApplicationContext
fun provideContext(): Context

@Component.Factory
interface Factory {
fun create(@BindsInstance @ApplicationContext context: Context): ApplicationComponent
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ru.otus.daggerhomework.di

import dagger.Component
import ru.otus.daggerhomework.FragmentProducer

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

fun inject(fragmentProducer: FragmentProducer)

@Component.Factory
interface Factory {
fun create(mainActivityComponent: MainActivityComponent): FragmentProducerComponent
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.otus.daggerhomework.di

import dagger.Module

@Module
object FragmentProducerModule {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И этот

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ru.otus.daggerhomework.di

import dagger.Component
import ru.otus.daggerhomework.FragmentProducer
import ru.otus.daggerhomework.FragmentReceiver

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

fun inject(fragmentReceiver: FragmentReceiver)

@Component.Factory
interface Factory {
fun create(mainActivityComponent: MainActivityComponent): FragmentReceiverComponent
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.otus.daggerhomework.di

import dagger.Module

@Module
object FragmentReceiverModule {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А зачем этот модуль?

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ru.otus.daggerhomework.di

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import ru.otus.daggerhomework.ColorGenerator
import ru.otus.daggerhomework.MainActivity

@Component(dependencies = [ApplicationComponent::class], modules = [MainModule::class])
@ActivityScope
interface MainActivityComponent {
fun provideContext():Context

fun provideColorGenerator(): ColorGenerator

fun provideMutableStateFlow(): MutableStateFlow<Int>
fun provideStateFlow(): StateFlow<Int>

@ApplicationContext
fun provideApplicationContext(): Context

@Component.Factory
interface Factory {
fun create(@BindsInstance context: Context, applicationComponent: ApplicationComponent): MainActivityComponent
}
}
Loading