diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index eae16063..89276e20 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ package="ru.otus.daggerhomework"> (R.id.button).setOnClickListener { - //отправить результат через flow в другой фрагмент + viewModel.generateColor() } } } \ No newline at end of file diff --git a/app/src/main/java/ru/otus/daggerhomework/ProducerViewModel.kt b/app/src/main/java/ru/otus/daggerhomework/ProducerViewModel.kt index 5bdf0271..b052507b 100644 --- a/app/src/main/java/ru/otus/daggerhomework/ProducerViewModel.kt +++ b/app/src/main/java/ru/otus/daggerhomework/ProducerViewModel.kt @@ -3,14 +3,17 @@ package ru.otus.daggerhomework import android.app.Activity import android.content.Context import android.widget.Toast +import kotlinx.coroutines.flow.MutableStateFlow class ProducerViewModel( private val colorGenerator: ColorGenerator, - private val context: Context + private val context: Context, + private val event: MutableStateFlow ) { fun generateColor() { if (context !is Activity) throw RuntimeException("Activity context is required") Toast.makeText(context, "Color sent", Toast.LENGTH_LONG).show() + event.value = Event.PopulateColor(color = colorGenerator.generateColor()) } } \ No newline at end of file diff --git a/app/src/main/java/ru/otus/daggerhomework/ReceiverFragment.kt b/app/src/main/java/ru/otus/daggerhomework/ReceiverFragment.kt index 9ba5f764..e2d49e36 100644 --- a/app/src/main/java/ru/otus/daggerhomework/ReceiverFragment.kt +++ b/app/src/main/java/ru/otus/daggerhomework/ReceiverFragment.kt @@ -6,25 +6,50 @@ import android.view.View import android.view.ViewGroup import androidx.annotation.ColorInt import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import kotlinx.coroutines.launch +import ru.otus.daggerhomework.di.DaggerReceiverFragmentComponent class ReceiverFragment : Fragment() { private lateinit var frame: View + private lateinit var viewModel: ReceiverViewModel + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_receiver, container, true) + val component = DaggerReceiverFragmentComponent + .factory() + .build( + requireActivity().application.component, + requireActivity().component + ) + viewModel = component.viewModel() + + 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 { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.event.collect { event -> + viewModel.observeColors() + when (event) { + is Event.PopulateColor -> populateColor(event.color) + } + } + } + } } - fun populateColor(@ColorInt color: Int) { + private fun populateColor(@ColorInt color: Int) { frame.setBackgroundColor(color) } } \ No newline at end of file diff --git a/app/src/main/java/ru/otus/daggerhomework/ReceiverViewModel.kt b/app/src/main/java/ru/otus/daggerhomework/ReceiverViewModel.kt index 250875a6..6367f112 100644 --- a/app/src/main/java/ru/otus/daggerhomework/ReceiverViewModel.kt +++ b/app/src/main/java/ru/otus/daggerhomework/ReceiverViewModel.kt @@ -3,11 +3,16 @@ package ru.otus.daggerhomework import android.app.Application import android.content.Context import android.widget.Toast +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.mapNotNull class ReceiverViewModel( - private val context: Context + private val context: Context, + event: MutableStateFlow ) { + val event = event.mapNotNull { it } + fun observeColors() { if (context !is Application) throw RuntimeException("Application context is required") Toast.makeText(context, "Color received", Toast.LENGTH_LONG).show() diff --git a/app/src/main/java/ru/otus/daggerhomework/di/ActivityContext.kt b/app/src/main/java/ru/otus/daggerhomework/di/ActivityContext.kt new file mode 100644 index 00000000..fd8c9e5d --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/ActivityContext.kt @@ -0,0 +1,7 @@ +package ru.otus.daggerhomework.di + +import javax.inject.Qualifier + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class ActivityContext() diff --git a/app/src/main/java/ru/otus/daggerhomework/di/ActivityScope.kt b/app/src/main/java/ru/otus/daggerhomework/di/ActivityScope.kt new file mode 100644 index 00000000..125bc656 --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/ActivityScope.kt @@ -0,0 +1,7 @@ +package ru.otus.daggerhomework.di + +import javax.inject.Scope + +@Scope +@Retention(value = AnnotationRetention.RUNTIME) +annotation class ActivityScope() diff --git a/app/src/main/java/ru/otus/daggerhomework/di/ApplicationComponent.kt b/app/src/main/java/ru/otus/daggerhomework/di/ApplicationComponent.kt new file mode 100644 index 00000000..2174b122 --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/ApplicationComponent.kt @@ -0,0 +1,19 @@ +package ru.otus.daggerhomework.di + +import android.content.Context +import dagger.BindsInstance +import dagger.Component +import javax.inject.Singleton + +@Singleton +@Component +interface ApplicationComponent { + + @Component.Factory + interface Factory { + fun build(@BindsInstance @ApplicationContext context: Context): ApplicationComponent + } + + @ApplicationContext + fun getContext(): Context +} \ No newline at end of file diff --git a/app/src/main/java/ru/otus/daggerhomework/di/ApplicationContext.kt b/app/src/main/java/ru/otus/daggerhomework/di/ApplicationContext.kt new file mode 100644 index 00000000..bb24880f --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/ApplicationContext.kt @@ -0,0 +1,7 @@ +package ru.otus.daggerhomework.di + +import javax.inject.Qualifier + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class ApplicationContext() diff --git a/app/src/main/java/ru/otus/daggerhomework/di/FragmentScope.kt b/app/src/main/java/ru/otus/daggerhomework/di/FragmentScope.kt new file mode 100644 index 00000000..78dc432b --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/FragmentScope.kt @@ -0,0 +1,7 @@ +package ru.otus.daggerhomework.di + +import javax.inject.Scope + +@Scope +@Retention(value = AnnotationRetention.RUNTIME) +annotation class FragmentScope() diff --git a/app/src/main/java/ru/otus/daggerhomework/di/MainActivityComponent.kt b/app/src/main/java/ru/otus/daggerhomework/di/MainActivityComponent.kt new file mode 100644 index 00000000..a28c46ee --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/MainActivityComponent.kt @@ -0,0 +1,21 @@ +package ru.otus.daggerhomework.di + +import android.content.Context +import dagger.BindsInstance +import dagger.Component +import kotlinx.coroutines.flow.MutableStateFlow +import ru.otus.daggerhomework.Event + +@ActivityScope +@Component(modules = [MainActivityModule::class]) +interface MainActivityComponent { + @Component.Factory + interface Factory { + fun build(@BindsInstance @ActivityContext context: Context): MainActivityComponent + } + + fun event(): MutableStateFlow + + @ActivityContext + fun getContext(): Context +} diff --git a/app/src/main/java/ru/otus/daggerhomework/di/MainActivityModule.kt b/app/src/main/java/ru/otus/daggerhomework/di/MainActivityModule.kt new file mode 100644 index 00000000..51f62371 --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/MainActivityModule.kt @@ -0,0 +1,13 @@ +package ru.otus.daggerhomework.di + +import dagger.Module +import dagger.Provides +import kotlinx.coroutines.flow.MutableStateFlow +import ru.otus.daggerhomework.Event + +@Module +class MainActivityModule { + @Provides + @ActivityScope + fun events(): MutableStateFlow = MutableStateFlow(null) +} \ No newline at end of file diff --git a/app/src/main/java/ru/otus/daggerhomework/di/ProducerFragmentComponent.kt b/app/src/main/java/ru/otus/daggerhomework/di/ProducerFragmentComponent.kt new file mode 100644 index 00000000..186a3137 --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/ProducerFragmentComponent.kt @@ -0,0 +1,22 @@ +package ru.otus.daggerhomework.di + +import dagger.Component +import ru.otus.daggerhomework.ProducerViewModel + +@Component( + dependencies = [MainActivityComponent::class], + modules = [ProducerModule::class] +) +@FragmentScope +interface ProducerFragmentComponent { + + @Component.Factory + interface Factory { + fun build( + mainActivityComponent: MainActivityComponent + ): ProducerFragmentComponent + } + + fun viewModel(): ProducerViewModel + +} \ No newline at end of file diff --git a/app/src/main/java/ru/otus/daggerhomework/di/ProducerModule.kt b/app/src/main/java/ru/otus/daggerhomework/di/ProducerModule.kt new file mode 100644 index 00000000..7c0bb783 --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/ProducerModule.kt @@ -0,0 +1,28 @@ +package ru.otus.daggerhomework.di + +import android.content.Context +import dagger.Module +import dagger.Provides +import kotlinx.coroutines.flow.MutableStateFlow +import ru.otus.daggerhomework.ColorGenerator +import ru.otus.daggerhomework.ColorGeneratorImpl +import ru.otus.daggerhomework.Event +import ru.otus.daggerhomework.ProducerViewModel + + +@Module +class ProducerModule { + + @Provides + @FragmentScope + fun colorGenerator(): ColorGenerator = ColorGeneratorImpl() + + @Provides + @FragmentScope + fun viewModel( + colorGenerator: ColorGenerator, + @ActivityContext + context: Context, + event: MutableStateFlow + ): ProducerViewModel = ProducerViewModel(colorGenerator, context, event) +} \ No newline at end of file diff --git a/app/src/main/java/ru/otus/daggerhomework/di/ReceiverFragmentComponent.kt b/app/src/main/java/ru/otus/daggerhomework/di/ReceiverFragmentComponent.kt new file mode 100644 index 00000000..c4859760 --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/ReceiverFragmentComponent.kt @@ -0,0 +1,22 @@ +package ru.otus.daggerhomework.di + +import dagger.Component +import ru.otus.daggerhomework.ReceiverViewModel + +@Component( + dependencies = [MainActivityComponent::class, ApplicationComponent::class], + modules = [ReceiverModule::class] +) +@FragmentScope +interface ReceiverFragmentComponent { + + @Component.Factory + interface Factory { + fun build( + applicationComponent: ApplicationComponent, + mainActivityComponent: MainActivityComponent + ): ReceiverFragmentComponent + } + + fun viewModel(): ReceiverViewModel +} \ No newline at end of file diff --git a/app/src/main/java/ru/otus/daggerhomework/di/ReceiverModule.kt b/app/src/main/java/ru/otus/daggerhomework/di/ReceiverModule.kt new file mode 100644 index 00000000..ed22a1c2 --- /dev/null +++ b/app/src/main/java/ru/otus/daggerhomework/di/ReceiverModule.kt @@ -0,0 +1,20 @@ +package ru.otus.daggerhomework.di + +import android.content.Context +import dagger.Module +import dagger.Provides +import kotlinx.coroutines.flow.MutableStateFlow +import ru.otus.daggerhomework.Event +import ru.otus.daggerhomework.ReceiverViewModel + +@Module +class ReceiverModule { + + @Provides + @FragmentScope + fun viewModel( + @ApplicationContext + context: Context, + event: MutableStateFlow + ): ReceiverViewModel = ReceiverViewModel(context, event) +} \ 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 79ae6993..602e0867 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,19 +1,32 @@ - - + + + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHeight_percent="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/fragment_producer" /> \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ab592426..32593ef3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.8.0" +agp = "8.5.1" kotlin = "2.0.20" coreKtx = "1.15.0" lifecycleRuntimeKtx = "2.8.7"