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: 10 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,21 @@ android {
}

dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
implementation 'androidx.activity:activity-ktx:1.2.3'

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'

implementation "com.google.dagger:dagger-android:2.42"
implementation "com.google.dagger:dagger-android-support:2.42"
kapt "com.google.dagger:dagger-android-processor:2.42"

implementation 'com.google.dagger:dagger:2.42'
kapt 'com.google.dagger:dagger-compiler:2.42'
}
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
10 changes: 10 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,14 @@ package ru.otus.daggerhomework
import android.app.Application

class App :Application() {
lateinit var appCompoment: ApplicationComponent
override fun onCreate() {
super.onCreate()
appCompoment = DaggerApplicationComponent.factory().newAppComponent(applicationContext)
}

}

fun Application.asApp(): App {
return this as App
}
22 changes: 21 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,24 @@
package ru.otus.daggerhomework

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 newAppComponent(@ApplicationContext @BindsInstance context: Context): ApplicationComponent
}
}

@Qualifier
annotation class ApplicationContext
4 changes: 2 additions & 2 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 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
7 changes: 7 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/EventsReader.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.otus.daggerhomework

import kotlinx.coroutines.flow.Flow

interface EventsReader {
val eventsFlow: Flow<Int>
}
5 changes: 5 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/EventsWriter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ru.otus.daggerhomework

interface EventsWriter {
fun writeEvent(color: Int)
}
17 changes: 17 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/EventsWriterReader.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ru.otus.daggerhomework

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import javax.inject.Inject

class EventsWriterReader @Inject constructor() : EventsReader, EventsWriter {
private val _eventsFlow = MutableSharedFlow<Int>(replay = 1)

override val eventsFlow: Flow<Int>
get() = _eventsFlow.asSharedFlow()

override fun writeEvent(color: Int) {
_eventsFlow.tryEmit(color)
}
}
9 changes: 7 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,26 @@ 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 viewModel: 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)
FragmentProducerComponent.getFragmentProducerComponent(
(requireActivity() as MainActivity).mainActivityComponent).inject(this)
view.findViewById<Button>(R.id.button).setOnClickListener {
//отправить результат через livedata в другой фрагмент
viewModel.generateColor()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ru.otus.daggerhomework

import dagger.Component
import javax.inject.Scope

@FragmentScope
@Component(
dependencies = [MainActivityComponent::class]
)
interface FragmentProducerComponent {
fun inject(fragmentProducer: FragmentProducer)

companion object {
fun getFragmentProducerComponent(mainActivityComponent: MainActivityComponent): FragmentProducerComponent {
return DaggerFragmentProducerComponent.builder()
.mainActivityComponent(mainActivityComponent).build()
}
}
}

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class FragmentScope
23 changes: 20 additions & 3 deletions app/src/main/java/ru/otus/daggerhomework/FragmentReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,45 @@ 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.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import javax.inject.Inject

class FragmentReceiver : Fragment() {

@Inject
lateinit var viewModel: 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)
FragmentReceiverComponent.getFragmentReceiverComponent(
(requireActivity() as MainActivity).mainActivityComponent).inject(this)
frame = view.findViewById(R.id.frame)
viewModel.initViewModel()
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED){
viewModel.eventsReader.eventsFlow.collect {
populateColor(it)
}
}
}
}

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

import dagger.Component

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

fun inject(fragmentReceiver: FragmentReceiver)

companion object {
fun getFragmentReceiverComponent(mainActivityComponent: MainActivityComponent): FragmentReceiverComponent {
return DaggerFragmentReceiverComponent.builder()
.mainActivityComponent(mainActivityComponent).build()
}
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
lateinit var mainActivityComponent: MainActivityComponent

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainActivityComponent = DaggerMainActivityComponent.factory().create(this, application.asApp().appCompoment)
supportFragmentManager.beginTransaction().add(R.id.container, FragmentReceiver()).commit()
supportFragmentManager.beginTransaction().add(R.id.container, FragmentProducer()).commit()
}
}
40 changes: 40 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,40 @@
package ru.otus.daggerhomework

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

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

fun getColorGenerator(): ColorGenerator

fun getEventReader(): EventsReader

fun getEventWriter(): EventsWriter

@ApplicationContext
fun provideContext(): Context

@ActivityContext
fun provideActivityContext(): Context

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

@Qualifier
annotation class ActivityContext

@Scope
annotation class ActivityScope
28 changes: 28 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/MainActivityModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ru.otus.daggerhomework

import dagger.Binds
import dagger.Module
import dagger.Provides

@Module
interface MainActivityModule {

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

@Binds
@ActivityScope
fun bindEventWriter(eventsWriter: EventsWriterReader): EventsWriter

@Binds
@ActivityScope
fun bindEventReader(eventsReader: EventsWriterReader): EventsReader

companion object{

@Provides
@ActivityScope
fun provideEventsReaderWriter() = EventsWriterReader()
Copy link
Contributor

Choose a reason for hiding this comment

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

А зачем тебе provides здесь. Достаточно Inject над конструктором

Copy link
Author

@GeorgeBozon GeorgeBozon Dec 8, 2024

Choose a reason for hiding this comment

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

ну да, поправлю

}
}
11 changes: 7 additions & 4 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,17 @@ package ru.otus.daggerhomework
import android.content.Context
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import javax.inject.Inject

class ViewModelProducer(
class ViewModelProducer @Inject constructor(
private val colorGenerator: ColorGenerator,
private val context: Context
) {
@ActivityContext 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.

Здесь будет утечка памяти, нельзя делать наследование от androidx.lifecycle.ViewModel

Copy link
Author

@GeorgeBozon GeorgeBozon Dec 8, 2024

Choose a reason for hiding this comment

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

исправил

private val eventsWriter: EventsWriter
){

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