diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt index 10fcb77d..09c16e29 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt @@ -1,7 +1,9 @@ package otus.homework.flowcats +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn class CatsRepository( private val catsService: CatsService, @@ -14,5 +16,5 @@ class CatsRepository( emit(latestNews) delay(refreshIntervalMs) } - } + }.flowOn(Dispatchers.IO) } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt index 6a195f3a..ac5bdb54 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt @@ -2,6 +2,8 @@ package otus.homework.flowcats import android.content.Context import android.util.AttributeSet +import android.view.View +import android.widget.ProgressBar import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout @@ -14,9 +16,18 @@ class CatsView @JvmOverloads constructor( override fun populate(fact: Fact) { findViewById(R.id.fact_textView).text = fact.text } + + override fun setLoadingVisible(visible: Boolean) { + findViewById(R.id.loading).visibility = if (visible) { + View.VISIBLE + } else { + View.GONE + } + } } interface ICatsView { fun populate(fact: Fact) + fun setLoadingVisible(visible: Boolean) } \ 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..57638400 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -1,27 +1,21 @@ package otus.homework.flowcats import androidx.lifecycle.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import kotlinx.coroutines.flow.* class CatsViewModel( private val catsRepository: CatsRepository ) : ViewModel() { - - private val _catsLiveData = MutableLiveData() - val catsLiveData: LiveData = _catsLiveData - - init { - viewModelScope.launch { - withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it - } - } + val catsState = catsRepository.listenForCatFacts() + .map { Result.Success(it) } + .catch> { + emit(Result.Error(it)) } - } + .stateIn( + viewModelScope, + SharingStarted.WhileSubscribed(5000), + Result.Loading + ) } class CatsViewModelFactory(private val catsRepository: CatsRepository) : diff --git a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt index edea434b..af8d1321 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -2,7 +2,11 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -14,8 +18,21 @@ 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.catsState.collect { + when (it) { + is Result.Success -> { + view.setLoadingVisible(false) + view.populate(it.data) + } + is Result.Error -> Toast.makeText( + this@MainActivity, + it.exception.message, + Toast.LENGTH_SHORT + ).show() + is Result.Loading -> view.setLoadingVisible(true) + } + } } } } \ 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..af816c1a --- /dev/null +++ b/flowcats/src/main/java/otus/homework/flowcats/Result.kt @@ -0,0 +1,7 @@ +package otus.homework.flowcats + +sealed class Result { + data class Success(val data: T) : Result() + data class Error(val exception: Throwable) : Result() + object Loading : Result() +} diff --git a/flowcats/src/main/res/layout/activity_main.xml b/flowcats/src/main/res/layout/activity_main.xml index dbcedd2f..5d5f6622 100644 --- a/flowcats/src/main/res/layout/activity_main.xml +++ b/flowcats/src/main/res/layout/activity_main.xml @@ -18,4 +18,15 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + \ 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..7ce98dbb 100644 --- a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt +++ b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt @@ -18,7 +18,11 @@ class SampleInteractor( * 6) возвращает результат */ fun task1(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .map { it * 5 } + .filter { it > 20 && it % 2 == 1 } + .take(3) + .map { "$it won" } } /** @@ -29,7 +33,17 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .transform { + emit("$it") + if (it % 15 == 0) { + emit("FizzBuzz") + } else if (it % 5 == 0) { + emit("Buzz") + } else if (it % 3 == 0) { + emit("Fizz") + } + } } /** @@ -38,7 +52,10 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + return sampleRepository.produceColors() + .zip(sampleRepository.produceForms()) { f1, f2 -> + Pair(f1, f2) + } } /** @@ -48,6 +65,13 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .catch { + when (it) { + is java.lang.IllegalArgumentException -> emit(-1) + else -> throw it + } + } + .onCompletion { sampleRepository.completed() } } } \ No newline at end of file