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
5 changes: 4 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ android {
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.6.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0" // For coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0" // For Android
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
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
12 changes: 11 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,15 @@ package ru.otus.daggerhomework

import android.app.Application

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

private lateinit var component: ApplicationComponent

override fun onCreate() {
super.onCreate()

component = DaggerApplicationComponent.factory().create(this)
}

fun getAppComponent(): ApplicationComponent = component
}
13 changes: 13 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,17 @@
package ru.otus.daggerhomework

import android.app.Application
import dagger.BindsInstance
import dagger.Component

@Component
interface ApplicationComponent {

fun provideApplication(): Application

@Component.Factory
interface Factory {

fun create(@BindsInstance application: Application): ApplicationComponent
}
}
6 changes: 3 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,16 @@ package ru.otus.daggerhomework

import android.graphics.Color
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import java.util.*
import java.util.Random
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
16 changes: 14 additions & 2 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,33 @@ 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 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)

DaggerFragmentProducerComponent
.builder()
.applicationComponent((requireActivity().application as App).getAppComponent())
.mainActivityComponent((requireActivity() as MainActivity).getComponent())
.build()
.inject(this)

view.findViewById<Button>(R.id.button).setOnClickListener {
//отправить результат через livedata в другой фрагмент
viewModelProducer.generateColor()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ru.otus.daggerhomework

import android.content.Context
import dagger.*
import kotlinx.coroutines.flow.MutableStateFlow

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

fun inject(fragmentProducer: FragmentProducer)
}

@Module
object ViewModelProducerModule {

@Provides
fun provide(colorGenerator: ColorGenerator, context: Context, flow: MutableStateFlow<Int>): ViewModelProducer {
return ViewModelProducer(colorGenerator, context, flow)
}
}
27 changes: 22 additions & 5 deletions app/src/main/java/ru/otus/daggerhomework/FragmentReceiver.kt
Original file line number Diff line number Diff line change
@@ -1,28 +1,45 @@
package ru.otus.daggerhomework

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.view.*
import androidx.annotation.ColorInt
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import kotlinx.coroutines.launch
import javax.inject.Inject

class FragmentReceiver : Fragment() {

@Inject
lateinit var viewModelReceiver: 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)

DaggerFragmentReceiverComponent
.builder()
.applicationComponent((requireActivity().application as App).getAppComponent())
.mainActivityComponent((requireActivity() as MainActivity).getComponent())
.build()
.inject(this)

frame = view.findViewById(R.id.frame)

lifecycleScope.launch {
viewModelReceiver.observeColors().collect { color ->
color.takeIf { it != -1 }?.let(::populateColor)
}
}
}

fun populateColor(@ColorInt color: Int) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ru.otus.daggerhomework

import android.app.Application
import dagger.*
import kotlinx.coroutines.flow.MutableStateFlow

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

fun inject(fragmentReceiver: FragmentReceiver)
}

@Module
object ViewModelReceiverModule {

@Provides
Copy link
Contributor

Choose a reason for hiding this comment

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

Тоже можно поменять на binds

Copy link
Author

Choose a reason for hiding this comment

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

Немного не понимаю как, я же тут из параметров создаю вьюмодель. По мне биндс не подходит
Можете по подробнее описать?

fun provide(context: Application, flow: MutableStateFlow<Int>): ViewModelReceiver {
return ViewModelReceiver(context, flow)
}
}
11 changes: 11 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,22 @@ package ru.otus.daggerhomework

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.coroutines.flow.*

class MainActivity : AppCompatActivity() {

private lateinit var mainActivityComponent: MainActivityComponent
private val flow: MutableStateFlow<Int> = MutableStateFlow(-1)

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

mainActivityComponent = DaggerMainActivityComponent.factory().create(this, flow)

supportFragmentManager.beginTransaction().add(R.id.container, FragmentReceiver()).commit()
supportFragmentManager.beginTransaction().add(R.id.container, FragmentProducer()).commit()
}

fun getComponent(): MainActivityComponent = mainActivityComponent
}
41 changes: 41 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,41 @@
package ru.otus.daggerhomework

import android.content.Context
import dagger.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

@Component(modules = [ColorGeneratorModule::class, StateFlowModule::class])
interface MainActivityComponent {

fun provideContext(): Context

fun provideFlow(): StateFlow<Int>

fun provideMutableFlow(): MutableStateFlow<Int>

fun provideColorGenerator(): ColorGenerator

@Component.Factory
interface Factory {

fun create(
@BindsInstance context: Context,
@BindsInstance flow: MutableStateFlow<Int>
): MainActivityComponent
}
}

@Module
interface ColorGeneratorModule {

@Binds
fun bindColorGenerator(colorGeneratorImpl: ColorGeneratorImpl): ColorGenerator
}

@Module
interface StateFlowModule {

@Binds
fun bindStateFlow(mutableStateFlow: MutableStateFlow<Int>): StateFlow<Int>
}
10 changes: 8 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,20 @@ package ru.otus.daggerhomework
import android.content.Context
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import kotlinx.coroutines.flow.*
import javax.inject.Inject

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

fun generateColor() {
if (context !is FragmentActivity) throw RuntimeException("Здесь нужен контекст активити")

flow.value = colorGenerator.generateColor()

Toast.makeText(context, "Color sent", Toast.LENGTH_LONG).show()
}
}
11 changes: 8 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,18 @@ package ru.otus.daggerhomework
import android.app.Application
import android.content.Context
import android.widget.Toast
import kotlinx.coroutines.flow.*
import javax.inject.Inject

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

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

return colorFlow
}
}
15 changes: 2 additions & 13 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container"
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"
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.constraintlayout.widget.ConstraintLayout>
tools:context=".MainActivity" />