Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dagger2Homework #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
11 changes: 9 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,11 @@ 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 'io.reactivex.rxjava2:rxjava:2.2.21'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "io.reactivex.rxjava2:rxkotlin:2.4.0"

implementation "androidx.activity:activity-ktx:1.4.0"
implementation 'androidx.fragment:fragment-ktx:1.4.0'
}
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
4 changes: 4 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,8 @@ package ru.otus.daggerhomework
import android.app.Application

class App :Application() {

val appComponent: ApplicationComponent by lazy {
DaggerApplicationComponent.factory().create(this)
}
}
47 changes: 46 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,49 @@
package ru.otus.daggerhomework

import android.content.Context
import androidx.lifecycle.ViewModel
import dagger.BindsInstance
import dagger.Component
import dagger.MapKey
import javax.inject.Qualifier
import javax.inject.Scope
import javax.inject.Singleton
import kotlin.reflect.KClass

@Singleton
@Component
interface ApplicationComponent {
}

@Component.Factory
interface Factory {
fun create(@BindsInstance @ApplicationContext context: Context): ApplicationComponent
}

@ApplicationContext
fun provideApplicationContext(): Context
}

@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER
)
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)

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

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

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class ApplicationContext

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class ActivityContext
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: 15 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,21 +6,35 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import javax.inject.Inject

class FragmentProducer : Fragment() {

@Inject
lateinit var viewModelFactory: ViewModelFactory

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.factory().create(
mainActivityComponent = (activity as MainActivity).mainActivityComponent
)
.inject(this)

val viewModelProducer: ViewModelProducer by viewModels { viewModelFactory }

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

import androidx.lifecycle.ViewModel
import dagger.Binds
import dagger.Component
import dagger.Module
import dagger.multibindings.IntoMap

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

@Component.Factory
interface Factory {
fun create(
mainActivityComponent: MainActivityComponent
): FragmentProducerComponent
}

fun inject(fragment: FragmentProducer)
}

@Module
interface ProducerModule {
@Binds
@FragmentScoped
fun bindColorGenerator(generator: ColorGeneratorImpl): ColorGenerator

@Binds
@IntoMap
@ViewModelKey(ViewModelProducer::class)
abstract fun viewModelProducer(viewModel: ViewModelProducer): ViewModel
}

22 changes: 19 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,44 @@ 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.fragment.app.viewModels
import javax.inject.Inject

class FragmentReceiver : Fragment() {

private lateinit var frame: View

@Inject
lateinit var viewModelFactory: ViewModelFactory

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)
frame = view.findViewById(R.id.frame)

DaggerFragmentReceiverComponent.factory().create(
applicationComponent = (requireActivity().application as App).appComponent,
mainActivityComponent = (activity as MainActivity).mainActivityComponent
)
.inject(this)
val viewModelReceiver: ViewModelReceiver by viewModels { viewModelFactory }

viewModelReceiver.observeColors()
viewModelReceiver.color.observe(viewLifecycleOwner) {
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,35 @@
package ru.otus.daggerhomework

import androidx.lifecycle.ViewModel
import dagger.Binds
import dagger.Component
import dagger.Module
import dagger.multibindings.IntoMap

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

@Component.Factory
interface Factory {
fun create(
applicationComponent: ApplicationComponent,
mainActivityComponent: MainActivityComponent
): FragmentReceiverComponent
}

fun inject(fragment: FragmentReceiver)
}

@Module
interface ReceiverModule {

@Binds
@IntoMap
@ViewModelKey(ViewModelReceiver::class)
abstract fun viewModelReceiver(viewModel: ViewModelReceiver): ViewModel
}

15 changes: 13 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
package ru.otus.daggerhomework

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import io.reactivex.subjects.PublishSubject

class MainActivity : AppCompatActivity() {

val mainActivityComponent: MainActivityComponent by lazy {
DaggerMainActivityComponent.factory().create(
applicationComponent = (application as App).appComponent,
context = this,
observer = PublishSubject.create()
)
}

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

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

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import io.reactivex.subjects.PublishSubject

@ActivityScoped
@Component(dependencies = [ApplicationComponent::class])
interface MainActivityComponent {
@Component.Factory
interface Factory {
fun create(
applicationComponent: ApplicationComponent,
@BindsInstance @ActivityContext context: Context,
@BindsInstance observer: PublishSubject<Int>
): MainActivityComponent
}

fun inject(activity: MainActivity)

fun provideObserver(): PublishSubject<Int>

@ActivityContext
fun provideActivityContext(): Context
}



15 changes: 15 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.otus.daggerhomework

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import javax.inject.Inject
import javax.inject.Provider

@FragmentScoped
class ViewModelFactory @Inject constructor(
private val viewModels: MutableMap<Class<out ViewModel>,
@JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T =
viewModels[modelClass]?.get() as T
}
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
@@ -1,19 +1,22 @@
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 io.reactivex.subjects.PublishSubject
import javax.inject.Inject

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

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