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
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package="ru.otus.daggerhomework">

<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
Expand Down
6 changes: 5 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,4 +2,8 @@ package ru.otus.daggerhomework

import android.app.Application

class App :Application()
class App : Application() {
val component by lazy {
DaggerApplicationComponent.factory().build(this) }

}
19 changes: 18 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/ApplicationComponent.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
package ru.otus.daggerhomework

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

@Singleton
@Component
interface ApplicationComponent {
}

@Component.Factory
interface Factory {
fun build(@BindsInstance app: App) : ApplicationComponent

Choose a reason for hiding this comment

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

  1. обычно метод в Factory называют create, build используют в Builder
  2. тут нужно пробросить Сontext, а не App
  3. нужно использовать квалификатор @ApplicationContext, потому что он может быть ActivityContext

}
}

16 changes: 13 additions & 3 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,26 @@ package ru.otus.daggerhomework

import android.graphics.Color
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import java.util.*
import dagger.Binds
import dagger.Module
import java.util.Random
import javax.inject.Inject

@Module
interface ColorGenModule {

@Binds
fun colorGenerator(impl: ColorGeneratorImpl) : ColorGenerator

}

interface ColorGenerator {

@ColorInt
fun generateColor(): Int
}

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

override fun generateColor(): Int {
val rnd = Random()
Expand Down
35 changes: 31 additions & 4 deletions app/src/main/java/ru/otus/daggerhomework/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
package ru.otus.daggerhomework

import android.graphics.Color
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.fragment.app.FragmentActivity
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Scope

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

class MainActivity() : FragmentActivity(), ColorSaver, ColorState
{
private val _state = MutableStateFlow(Color.BLACK)

override val color: StateFlow<Int> = _state

override fun saveColor(color: Int) {
_state.value = color
}

lateinit var component: MainActivityComponent

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
component = DaggerMainActivityComponent.factory().build(applicationContext,this)
try {
setContentView(R.layout.activity_main)
}
catch (e: Exception) {
println(e)
}
}
}
}

val MainActivity.Component: MainActivityComponent get() = this.component

Choose a reason for hiding this comment

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

обычно свойства с маленькой буквы MainActivity.сomponent

57 changes: 57 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,57 @@
package ru.otus.daggerhomework

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Qualifier

@MainActivityScope
@Component(

Choose a reason for hiding this comment

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

это должен быть Subcomponent для ApplicationComponent, а не отдельный компонент

modules = [ColorModule::class, MainActivityModule::class])
interface MainActivityComponent {

@Component.Factory
interface Factory {
fun build(@BindsInstance appContext: Context,

Choose a reason for hiding this comment

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

тут не нужно прокидывать и appContext и activity, достаточно будет @MainActivityContext context: Context, соответственно нужно создать @ApplicationContext аннотации:

@Qualifier
annotation class ApplicationContext

@BindsInstance activity: MainActivity): MainActivityComponent
}

fun producerComponent(): ProducerFragmentComponent.Factory

fun receiverComponent(): ReceiverFragmentComponent.Factory
}

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

@Module
object MainActivityModule {

Choose a reason for hiding this comment

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

этот модуль будет не нужен

@Provides
@MainActivityContext
fun getMainActivityContext(activity: MainActivity): Context = activity

}

@Module
class ColorModule {

@Provides
@MainActivityScope
fun colorState(activity: MainActivity) : ColorState = activity

@Provides
@MainActivityScope
fun colorSetter(activity: MainActivity) : ColorSaver = activity
}

interface ColorSaver{
fun saveColor(color: Int)
}

interface ColorState{
val color: StateFlow<Int>
}
17 changes: 15 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/ProducerFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,34 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import javax.inject.Inject
import javax.inject.Scope

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

class ProducerFragment : Fragment() {

@Inject
lateinit var model: ProducerViewModel

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_producer, container, true)
(requireActivity() as MainActivity).Component
.producerComponent()
.create()
.inject(this)
return inflater.inflate(R.layout.fragment_producer, container, false)
}

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

import dagger.Subcomponent

@ProducerFragmentScope
@Subcomponent(
modules = [ColorGenModule::class])
interface ProducerFragmentComponent {

@Subcomponent.Factory
interface Factory {
fun create(): ProducerFragmentComponent
}

fun inject(fragment: ProducerFragment)
}
9 changes: 6 additions & 3 deletions app/src/main/java/ru/otus/daggerhomework/ProducerViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ package ru.otus.daggerhomework
import android.app.Activity
import android.content.Context
import android.widget.Toast
import javax.inject.Inject

class ProducerViewModel(
class ProducerViewModel @Inject constructor (
private val color: ColorSaver,
private val colorGenerator: ColorGenerator,
private val context: Context
@param:MainActivityContext private val context: Context

Choose a reason for hiding this comment

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

тут получаем @ActivityContext

) {

fun generateColor() {
if (context !is Activity) throw RuntimeException("Activity context is required")
color.saveColor(colorGenerator.generateColor())
Toast.makeText(context, "Color sent", Toast.LENGTH_LONG).show()
}
}
}
23 changes: 21 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/ReceiverFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,44 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.ColorInt
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import javax.inject.Inject
import javax.inject.Scope


@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class ReceiverFragmentScope()
class ReceiverFragment : Fragment() {

@Inject
lateinit var model: ReceiverViewModel
private lateinit var frame: View

lateinit var component: ReceiverFragmentComponent

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_receiver, container, true)
component = (requireActivity() as MainActivity).Component.receiverComponent().create()
component.inject(this)
return inflater.inflate(R.layout.fragment_receiver, container, false)
}

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

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

import dagger.Subcomponent

@ReceiverFragmentScope
@Subcomponent()
interface ReceiverFragmentComponent {

@Subcomponent.Factory
interface Factory {
fun create(): ReceiverFragmentComponent
}

fun inject(fragment: ReceiverFragment)

}
8 changes: 6 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/ReceiverViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ package ru.otus.daggerhomework
import android.app.Application
import android.content.Context
import android.widget.Toast
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject

class ReceiverViewModel(
class ReceiverViewModel @Inject constructor(
private val state: ColorState,
private val context: Context

Choose a reason for hiding this comment

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

тут мы получаем @ApplicationContext

) {

fun observeColors() {
fun observeColors(): StateFlow<Int> {
if (context !is Application) throw RuntimeException("Application context is required")
Toast.makeText(context, "Color received", Toast.LENGTH_LONG).show()
return state.color
}
}
29 changes: 18 additions & 11 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:name="ru.otus.daggerhomework.ProducerFragment"
tools:layout="@layout/fragment_producer" />

</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="ru.otus.daggerhomework.ReceiverFragment"
tools:layout="@layout/fragment_receiver" />

</LinearLayout>
2 changes: 1 addition & 1 deletion app/src/main/res/layout/fragment_receiver.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"/>
Loading