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
18 changes: 12 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.kapt'
}

android {
compileSdkVersion 31
compileSdkVersion 34

defaultConfig {
applicationId "ru.otus.daggerhomework"
minSdkVersion 23
targetSdkVersion 31
targetSdkVersion 34
versionCode 1
versionName "1.0"

Expand All @@ -30,6 +30,7 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
namespace 'ru.otus.daggerhomework'
}

dependencies {
Expand All @@ -38,6 +39,11 @@ dependencies {
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:2.42'
kapt 'com.google.dagger:dagger-compiler:2.42'
implementation 'com.google.dagger:dagger:2.48'
kapt 'com.google.dagger:dagger-compiler:2.48'

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
implementation 'androidx.fragment:fragment-ktx:1.6.2'
}
9 changes: 5 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.otus.daggerhomework">
xmlns:android="http://schemas.android.com/apk/res/android">

<application
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">
android:theme="@style/Theme.DaggerHomework"
android:name=".di.app.App">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
6 changes: 0 additions & 6 deletions app/src/main/java/ru/otus/daggerhomework/App.kt

This file was deleted.

This file was deleted.

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
32 changes: 30 additions & 2 deletions app/src/main/java/ru/otus/daggerhomework/FragmentProducer.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,54 @@
package ru.otus.daggerhomework

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import ru.otus.daggerhomework.di.activity.ActivityComponentHolder
import ru.otus.daggerhomework.di.app.appComponent
import ru.otus.daggerhomework.di.fragments.DaggerFragmentProducerComponent
import javax.inject.Inject

class FragmentProducer : Fragment() {

@Inject
lateinit var viewModel: ViewModelProducer2

override fun onAttach(context: Context) {
super.onAttach(context)
DaggerFragmentProducerComponent
.builder()
.setActivityComponent(
ActivityComponentHolder
.getActivityComponent(
context.appComponent,
requireActivity()
)
)
.build()
.inject(this)
}

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)
view.findViewById<Button>(R.id.button).setOnClickListener {
//отправить результат через livedata в другой фрагмент
viewModel.generateColor()
}
}

override fun onDestroyView() {
viewModel.disposeResources()
super.onDestroyView()
}
}
56 changes: 52 additions & 4 deletions app/src/main/java/ru/otus/daggerhomework/FragmentReceiver.kt
Original file line number Diff line number Diff line change
@@ -1,31 +1,79 @@
package ru.otus.daggerhomework

import android.content.Context
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 ru.otus.daggerhomework.di.activity.ActivityComponentHolder
import ru.otus.daggerhomework.di.app.appComponent
import ru.otus.daggerhomework.di.fragments.DaggerFragmentReceiverComponent
import javax.inject.Inject

class FragmentReceiver : Fragment() {

private lateinit var frame: View

@Inject
lateinit var viewModel: ViewModelReceiver2

private var currentColor: Int = 0xFFFFFF

override fun onAttach(context: Context) {
super.onAttach(context)
DaggerFragmentReceiverComponent
.builder()
.setActivityComponent(
ActivityComponentHolder
.getActivityComponent(
context.appComponent,
requireActivity()
)
)
.build()
.inject(this)
}

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)

viewModel.observeColors(::populateColor)
}

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

override fun onSaveInstanceState(outState: Bundle) {
outState.putInt(COLOR_KEY, currentColor)
super.onSaveInstanceState(outState)
}

override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
if (savedInstanceState != null) {
populateColor(savedInstanceState.getInt(COLOR_KEY, currentColor))
}
}

override fun onDestroyView() {
viewModel.disposeResources()
super.onDestroyView()
}

fun populateColor(@ColorInt color: Int) {
frame.setBackgroundColor(color)
companion object {
private const val COLOR_KEY = "color"
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/LocalEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ru.otus.daggerhomework

import androidx.annotation.ColorInt

sealed interface LocalEvent {
data class ColorData(
@ColorInt val color: Int
): LocalEvent
data class Error(
val e: Exception
): LocalEvent
}
13 changes: 12 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package ru.otus.daggerhomework

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import ru.otus.daggerhomework.di.activity.ActivityComponentHolder
import ru.otus.daggerhomework.di.app.appComponent

class MainActivity : AppCompatActivity() {

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

// supportFragmentManager.beginTransaction()
// .replace(R.id.fragment_producer_container, FragmentProducer())
// .replace(R.id.fragment_receiver_container, FragmentReceiver())
// .commit()

ActivityComponentHolder
.getActivityComponent(application.appComponent, this)
.inject(this)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ru.otus.daggerhomework

interface ViewModelMarkerInterface {
fun disposeResources()
}
30 changes: 27 additions & 3 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,38 @@ package ru.otus.daggerhomework
import android.content.Context
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import ru.otus.daggerhomework.di.activity.ActivityContextQualifier
import java.lang.ref.WeakReference
import javax.inject.Inject

class ViewModelProducer(
class ViewModelProducer @Inject constructor(
private val observer: Channel<LocalEvent>,
private val colorGenerator: ColorGenerator,
@ActivityContextQualifier
activityContext: Context
) : ViewModel() {

private val weakContextRef = WeakReference(activityContext)
private val context: Context
) {
get() = weakContextRef.get()!!

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

viewModelScope.launch {
try {
observer.send(LocalEvent.ColorData(colorGenerator.generateColor()))
Toast.makeText(context, "Color sent", Toast.LENGTH_SHORT).show()
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
observer.send(LocalEvent.Error(e))
}
}
}
}
43 changes: 43 additions & 0 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelProducer2.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ru.otus.daggerhomework

import android.content.Context
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.launch
import ru.otus.daggerhomework.di.activity.ActivityContextQualifier
import javax.inject.Inject

class ViewModelProducer2 @Inject constructor(
private val observable: SendChannel<@JvmSuppressWildcards LocalEvent>,
private val colorGenerator: ColorGenerator,
@ActivityContextQualifier
private val activityContext: Context
) : ViewModelMarkerInterface {

private val viewModelScope = CoroutineScope(Dispatchers.Main.immediate + SupervisorJob())

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

viewModelScope.launch {
try {
observable.send(LocalEvent.ColorData(colorGenerator.generateColor()))
Toast.makeText(activityContext, "Color sent", Toast.LENGTH_SHORT).show()
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
observable.send(LocalEvent.Error(e))
}
}
}

override fun disposeResources() {
viewModelScope.cancel()
}
}
Loading