From dd02c4da042622dba8bbe1db0b184a888854a290 Mon Sep 17 00:00:00 2001 From: Miksim Lobzhanidze Date: Thu, 22 Aug 2024 06:51:32 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=B7=20=E2=84=963=20=D0=BF=D0=BE=20flow?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otus/homework/flowcats/CatsViewModel.kt | 27 +++++++---- .../otus/homework/flowcats/MainActivity.kt | 14 ++++-- .../java/otus/homework/flowcats/Result.kt | 13 +++++ .../otus/homework/flow/SampleInteractor.kt | 47 +++++++++++++++++-- 4 files changed, 83 insertions(+), 18 deletions(-) create mode 100644 flowcats/src/main/java/otus/homework/flowcats/Result.kt diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt index 0d8ba8a7..838dcc10 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -1,31 +1,38 @@ package otus.homework.flowcats -import androidx.lifecycle.* -import kotlinx.coroutines.Dispatchers +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.onStart 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 _catsFlow = MutableStateFlow(Result.Initial) + val catsFlow: StateFlow = _catsFlow.asStateFlow() init { viewModelScope.launch { - withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it + catsRepository.listenForCatFacts() + .onStart { _catsFlow.value = Result.Loading } + .catch { _catsFlow.value = Result.Error } + .collect { + _catsFlow.value = Result.Success(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..35dfc232 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -3,6 +3,11 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -14,8 +19,11 @@ class MainActivity : AppCompatActivity() { val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView setContentView(view) - catsViewModel.catsLiveData.observe(this){ - view.populate(it) - } + catsViewModel.catsFlow.onEach { result -> + when(result) { + is Result.Success -> view.populate(result.fact) + else -> Unit + } + }.launchIn(lifecycleScope) } } \ 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..978f49d6 --- /dev/null +++ b/flowcats/src/main/java/otus/homework/flowcats/Result.kt @@ -0,0 +1,13 @@ +package otus.homework.flowcats + +sealed class Result { + data class Success(val fact: Fact): Result() + + data object Error: Result() + + data object Initial: Result() + + data object Loading: Result() + + +} \ 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..7f6637f4 100644 --- a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt +++ b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt @@ -18,9 +18,15 @@ 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) } + /** * Классическая задача FizzBuzz с небольшим изменением. * Если входное число делится на 3 - эмитим само число и после него эмитим строку Fizz @@ -28,8 +34,28 @@ class SampleInteractor( * Если входное число делится на 15 - эмитим само число и после него эмитим строку FizzBuzz * Если число не делится на 3,5,15 - эмитим само число */ - fun task2(): Flow { - return flowOf() + fun task2() = flow { + sampleRepository.produceNumbers() + .collect { + when { + it % 15 == 0 -> { + emit("$it") + emit("FizzBuzz") + } + it % 3 == 0 -> { + emit("$it") + emit("Fizz") + + } + it % 5 == 0 -> { + emit("$it") + emit("Buzz") + } + else -> { + emit("$it") + } + } + } } /** @@ -38,7 +64,8 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + return sampleRepository.produceColors() + .zip(sampleRepository.produceForms()) { t1, t2 -> Pair(t1, t2) } } /** @@ -48,6 +75,16 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .catch() { e -> + if(e is IllegalArgumentException) { + emit(-1) + } else { + throw e + } + } + .onCompletion { + sampleRepository.completed() + } } } \ No newline at end of file