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
10 changes: 8 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 @@ -41,4 +41,10 @@ dependencies {
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 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'

implementation 'androidx.fragment:fragment-ktx:1.4.1'
// implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.0-rc01")
}
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: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
13 changes: 12 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,17 @@
package ru.otus.daggerhomework

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

class App : Application() {

val componentInstance: ApplicationComponent by lazy {
createApplicationComponent()
}

private fun createApplicationComponent(): ApplicationComponent = DaggerApplicationComponent
.factory()
.create(context = this)

class App :Application() {
}

This file was deleted.

11 changes: 8 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,19 +2,24 @@ 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()
return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))
return Color.argb(
255,
rnd.nextInt(256),
rnd.nextInt(256),
rnd.nextInt(256)
)
}
}
21 changes: 20 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,9 +6,19 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import javax.inject.Inject

class FragmentProducer : Fragment() {

@Inject
lateinit var viewModelProducer: ViewModelProducer

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

injectDependencies()
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand All @@ -20,7 +30,16 @@ class FragmentProducer : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.button).setOnClickListener {
//отправить результат через livedata в другой фрагмент
viewModelProducer.generateColor()
}
}

private fun injectDependencies() {
val component = (activity as MainActivity)
.activityComponent
.provideFragmentProducerComponentFactory()
.create()

component.inject(this)
}
}
31 changes: 29 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,14 +4,26 @@ 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.lifecycleScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import javax.inject.Inject

class FragmentReceiver : Fragment() {

@Inject
lateinit var viewModelReceiver: ViewModelReceiver

private lateinit var frame: View

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

injectDependencies()
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand All @@ -23,9 +35,24 @@ class FragmentReceiver : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
frame = view.findViewById(R.id.frame)

viewLifecycleOwner.lifecycleScope.launch {
viewModelReceiver
.colorsFlow
.collect(this@FragmentReceiver::populateColor)
}
}

fun populateColor(@ColorInt color: Int) {
private fun populateColor(@ColorInt color: Int) {
frame.setBackgroundColor(color)
}

private fun injectDependencies() {
val component = (activity as MainActivity)
.activityComponent
.provideFragmentReceiverComponentFactory()
.create()

component.inject(this)
}
}
25 changes: 24 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,34 @@
package ru.otus.daggerhomework

import androidx.appcompat.app.AppCompatActivity
import android.content.Context
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import ru.otus.daggerhomework.di.activity.ActivityComponent
import ru.otus.daggerhomework.di.qualifiers.AppContext
import javax.inject.Inject

class MainActivity : AppCompatActivity() {

@AppContext
@Inject
lateinit var appContext: Context

val activityComponent: ActivityComponent by lazy {
createActivityComponent()
}

override fun onCreate(savedInstanceState: Bundle?) {
injectDependencies()
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}

private fun injectDependencies() {
activityComponent.inject(this)
}

private fun createActivityComponent(): ActivityComponent = (application as App)
.componentInstance
.provideActivityComponentFactory()
.create(context = this)
}
14 changes: 8 additions & 6 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelProducer.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
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 java.lang.RuntimeException
import kotlinx.coroutines.flow.MutableStateFlow
import ru.otus.daggerhomework.di.qualifiers.ActivityContext
import javax.inject.Inject

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

fun generateColor() {
if (context !is FragmentActivity) throw RuntimeException("Здесь нужен контекст активити")
Toast.makeText(context, "Color sent", Toast.LENGTH_LONG).show()
stateFlow.value = colorGenerator.generateColor()
}
}
22 changes: 15 additions & 7 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@ package ru.otus.daggerhomework

import android.app.Application
import android.content.Context
import android.util.Log
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import java.lang.RuntimeException
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.onEach
import ru.otus.daggerhomework.di.qualifiers.AppContext
import javax.inject.Inject

class ViewModelReceiver(
private val context: Context
) : ViewModel() {
class ViewModelReceiver @Inject constructor(
@AppContext private val context: Context,
flow: StateFlow<Int>
) {

fun observeColors() {
val colorsFlow = flow
.filter { it != 0 }
.onEach { observeColors() }

private fun observeColors() {
if (context !is Application) throw RuntimeException("Здесь нужен контекст апликейшена")
Toast.makeText(context, "Color received", Toast.LENGTH_LONG).show()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ru.otus.daggerhomework.di.activity

import android.content.Context
import dagger.BindsInstance
import dagger.Module
import dagger.Provides
import dagger.Subcomponent
import kotlinx.coroutines.flow.MutableStateFlow
import ru.otus.daggerhomework.MainActivity
import ru.otus.daggerhomework.di.customscopes.ActivityScope
import ru.otus.daggerhomework.di.fragment.FragmentProducerComponent
import ru.otus.daggerhomework.di.fragment.FragmentReceiverComponent
import ru.otus.daggerhomework.di.qualifiers.ActivityContext

@ActivityScope
@Subcomponent(modules = [ActivityComponentModule::class])
interface ActivityComponent {

fun provideFragmentProducerComponentFactory(): FragmentProducerComponent.Factory

fun provideFragmentReceiverComponentFactory(): FragmentReceiverComponent.Factory

fun inject(activity: MainActivity)

@Subcomponent.Factory
interface Factory {
fun create(
@ActivityContext
@BindsInstance
context: Context
): ActivityComponent
}
}

@Module(
subcomponents = [
FragmentProducerComponent::class,
FragmentProducerComponent::class
]
)
class ActivityComponentModule {

@ActivityScope
@Provides
fun provideObserver(): MutableStateFlow<Int> = MutableStateFlow(0)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ru.otus.daggerhomework.di.app

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import dagger.Module
import ru.otus.daggerhomework.di.activity.ActivityComponent
import ru.otus.daggerhomework.di.qualifiers.AppContext
import javax.inject.Singleton

@Singleton
@Component(modules = [ApplicationComponentModule::class])
interface ApplicationComponent {

fun provideActivityComponentFactory(): ActivityComponent.Factory

@Component.Factory
interface Factory {

fun create(
@AppContext
@BindsInstance
context: Context
): ApplicationComponent
}
}

@Module(subcomponents = [ActivityComponent::class])
class ApplicationComponentModule
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,6 @@
package ru.otus.daggerhomework.di.customscopes

import javax.inject.Scope

@Scope
annotation class ActivityScope
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ru.otus.daggerhomework.di.customscopes

import javax.inject.Scope

@Scope
annotation class AppScope
Loading