From b526d83842436c845f51e38200c0f0da5fe02a86 Mon Sep 17 00:00:00 2001 From: "a.batrakov" Date: Wed, 22 Apr 2026 00:15:12 +0300 Subject: [PATCH] do homework --- .../java/otus/homework/flowcats/CatsView.kt | 33 +++++++++++++---- .../otus/homework/flowcats/CatsViewModel.kt | 22 ++++++----- .../otus/homework/flowcats/MainActivity.kt | 9 ++++- .../java/otus/homework/flowcats/Result.kt | 9 +++++ .../src/main/res/layout/activity_main.xml | 14 +++++-- flowcats/src/main/res/values/strings.xml | 1 + .../otus/homework/flow/SampleInteractor.kt | 37 +++++++++++++++++-- 7 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 flowcats/src/main/java/otus/homework/flowcats/Result.kt diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt index 6a195f3a..7c18bd8d 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt @@ -2,21 +2,38 @@ package otus.homework.flowcats import android.content.Context import android.util.AttributeSet +import android.view.View +import android.widget.FrameLayout import android.widget.TextView -import androidx.constraintlayout.widget.ConstraintLayout class CatsView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : ConstraintLayout(context, attrs, defStyleAttr), ICatsView { +) : FrameLayout(context, attrs, defStyleAttr) { - override fun populate(fact: Fact) { - findViewById(R.id.fact_textView).text = fact.text - } -} + private val factTextView: TextView by lazy { findViewById(R.id.fact_textView) } + private val progressBar: View by lazy { findViewById(R.id.progressBar) } + + fun render(result: Result) { + when (result) { -interface ICatsView { + is Result.Loading -> { + progressBar.visibility = VISIBLE + factTextView.visibility = GONE + } - fun populate(fact: Fact) + is Result.Success -> { + progressBar.visibility = GONE + factTextView.visibility = VISIBLE + factTextView.text = result.fact.text + } + + is Result.Error -> { + progressBar.visibility = GONE + factTextView.visibility = VISIBLE + factTextView.text = context.getString(R.string.error_text) + } + } + } } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt index 0d8ba8a7..748876b6 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -1,31 +1,35 @@ package otus.homework.flowcats +import android.util.Log import androidx.lifecycle.* -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class CatsViewModel( private val catsRepository: CatsRepository ) : ViewModel() { - private val _catsLiveData = MutableLiveData() - val catsLiveData: LiveData = _catsLiveData + private val _catsStateFlowData = MutableStateFlow(Result.Loading) + val catsStateFlowData: StateFlow = _catsStateFlowData init { viewModelScope.launch { - withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it - } + catsRepository.listenForCatFacts().catch { e -> + _catsStateFlowData.value = Result.Error(e) + Log.e("ApiError", e.toString()) } + .collect { + _catsStateFlowData.value = Result.Success(fact = it) + } } } } class CatsViewModelFactory(private val catsRepository: CatsRepository) : ViewModelProvider.NewInstanceFactory() { - override fun create(modelClass: Class): T = + override fun create(modelClass: Class): T = CatsViewModel(catsRepository) as T } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt index edea434b..527001ad 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -3,6 +3,9 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.collect class MainActivity : AppCompatActivity() { @@ -14,8 +17,10 @@ class MainActivity : AppCompatActivity() { val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView setContentView(view) - catsViewModel.catsLiveData.observe(this){ - view.populate(it) + lifecycleScope.launch { + catsViewModel.catsStateFlowData.collect {result -> + view.render(result) + } } } } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/Result.kt b/flowcats/src/main/java/otus/homework/flowcats/Result.kt new file mode 100644 index 00000000..0d6e0a7a --- /dev/null +++ b/flowcats/src/main/java/otus/homework/flowcats/Result.kt @@ -0,0 +1,9 @@ +package otus.homework.flowcats + +sealed class Result { + data class Success(val fact: Fact) : Result() + + data class Error(val e: Throwable) : Result() + + object Loading : Result() +} \ No newline at end of file diff --git a/flowcats/src/main/res/layout/activity_main.xml b/flowcats/src/main/res/layout/activity_main.xml index dbcedd2f..5049efc9 100644 --- a/flowcats/src/main/res/layout/activity_main.xml +++ b/flowcats/src/main/res/layout/activity_main.xml @@ -13,9 +13,15 @@ android:layout_height="wrap_content" android:textColor="@color/black" android:textSize="24sp" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + android:visibility="gone" + android:layout_gravity="center" + /> + + \ No newline at end of file diff --git a/flowcats/src/main/res/values/strings.xml b/flowcats/src/main/res/values/strings.xml index ba737b82..165aa0b1 100644 --- a/flowcats/src/main/res/values/strings.xml +++ b/flowcats/src/main/res/values/strings.xml @@ -1,3 +1,4 @@ Flow cats + Произошла ошибка, попробуйете позже \ No newline at end of file diff --git a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt index 1993c064..c72fa40f 100644 --- a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt +++ b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt @@ -18,7 +18,7 @@ class SampleInteractor( * 6) возвращает результат */ fun task1(): Flow { - return flowOf() + return sampleRepository.produceNumbers().map { it*5 }.filter { it>20 }.filter { it%2!=0 }.map { "$it won" }.take(3) } /** @@ -29,7 +29,28 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .flatMapConcat { + flow { + when { + (it % 15 == 0) -> { + emit(it.toString()) + emit("FizzBuzz") + } + (it % 5 == 0) -> { + emit(it.toString()) + emit("Buzz") + } + (it % 3 == 0) -> { + emit(it.toString()) + emit("Fizz") + } + else -> { + emit(it.toString()) + } + } + } + } } /** @@ -38,7 +59,11 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + val a = sampleRepository.produceColors() + val b = sampleRepository.produceForms() + return a.zip(b) { + a,b -> Pair(a,b) + } } /** @@ -48,6 +73,10 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + return sampleRepository.produceNumbers().onStart({ sampleRepository.completed() }).catch { e -> + if (e is IllegalArgumentException) { + emit(-1) + } else throw e + } } } \ No newline at end of file