From 06e8a6256cd6a728afa5ea7a93ab33eae7bc8dea Mon Sep 17 00:00:00 2001 From: Kirill Date: Mon, 22 Apr 2024 10:19:30 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=BC=D0=B0=D1=88=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- flowcats/build.gradle | 24 ++++---- flowcats/src/main/AndroidManifest.xml | 6 +- .../java/otus/homework/flowcats/CatsView.kt | 6 +- .../otus/homework/flowcats/CatsViewModel.kt | 31 ++++++---- .../otus/homework/flowcats/MainActivity.kt | 16 ++++- gradle.properties | 5 +- gradle/wrapper/gradle-wrapper.properties | 2 +- operators/build.gradle | 3 +- operators/src/main/AndroidManifest.xml | 3 +- .../otus/homework/flow/SampleInteractor.kt | 61 +++++++++++++++++-- .../otus/homework/flow/SampleRepository.kt | 1 + 12 files changed, 117 insertions(+), 45 deletions(-) diff --git a/build.gradle b/build.gradle index e47bb55b..2a7fbbf4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.4.32" + ext.kotlin_version = '1.8.22' repositories { google() jcenter() } dependencies { - classpath "com.android.tools.build:gradle:4.1.2" + classpath 'com.android.tools.build:gradle:8.3.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/flowcats/build.gradle b/flowcats/build.gradle index cefa21e0..25c005bd 100644 --- a/flowcats/build.gradle +++ b/flowcats/build.gradle @@ -4,13 +4,13 @@ plugins { } android { - compileSdkVersion 30 + compileSdkVersion 34 buildToolsVersion "30.0.3" defaultConfig { applicationId "otus.homework.flowcats" minSdkVersion 23 - targetSdkVersion 30 + targetSdkVersion 34 versionCode 1 versionName "1.0" @@ -30,20 +30,22 @@ android { kotlinOptions { jvmTarget = '1.8' } + namespace 'otus.homework.flowcats' } dependencies { + //noinspection GradleDependency implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.core:core-ktx:1.13.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' - implementation 'com.google.code.gson:gson:2.8.6' - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.3.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'com.google.code.gson:gson:2.10.1' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.11.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'com.squareup.picasso:picasso:2.71828' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3' - implementation 'androidx.activity:activity-ktx:1.2.3' - testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.3' - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3' + implementation 'androidx.activity:activity-ktx:1.9.0' + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0' } \ No newline at end of file diff --git a/flowcats/src/main/AndroidManifest.xml b/flowcats/src/main/AndroidManifest.xml index 2deb6454..feb3f274 100644 --- a/flowcats/src/main/AndroidManifest.xml +++ b/flowcats/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + - + diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt index 6a195f3a..b17dc960 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsView.kt @@ -11,12 +11,12 @@ class CatsView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr), ICatsView { - override fun populate(fact: Fact) { - findViewById(R.id.fact_textView).text = fact.text + override fun populate(fact: Success) { + findViewById(R.id.fact_textView).text = fact.data.text } } interface ICatsView { - fun populate(fact: Fact) + fun populate(fact: Success) } \ 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..ca8b0ef1 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -1,24 +1,27 @@ package otus.homework.flowcats -import androidx.lifecycle.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.collect +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch 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 _cats: MutableStateFlow = + MutableStateFlow(Success(Fact("", false, "", "", "", false, "", "", ""))) + val cats = _cats.asStateFlow() init { viewModelScope.launch { - withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it - } + catsRepository.listenForCatFacts() + .catch { _cats.value = Error } + .collect { + _cats.value = Success(it) } } } @@ -26,6 +29,10 @@ class CatsViewModel( 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 +} + +sealed class Result +data class Success(val data: Fact) : Result() +object Error : Result() \ 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..1095b972 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -2,7 +2,12 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -14,8 +19,15 @@ 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 { + lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED){ + catsViewModel.cats.collect{result -> + when(result){ + Error -> Toast.makeText(this@MainActivity, "Не удалось получить ответ от сервера", Toast.LENGTH_SHORT).show() + is Success -> view.populate(result) + } + } + } } } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 98bed167..8145fa7b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,7 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +kotlin.code.style=official +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 88fa9252..0c43d4db 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip diff --git a/operators/build.gradle b/operators/build.gradle index 39c4b952..d6a5fc9d 100644 --- a/operators/build.gradle +++ b/operators/build.gradle @@ -10,8 +10,6 @@ android { minSdkVersion 23 targetSdkVersion 30 - versionCode 1 - versionName "1.0" } compileOptions { @@ -21,6 +19,7 @@ android { kotlinOptions { jvmTarget = '1.8' } + namespace 'otus.homework.flow' } dependencies { diff --git a/operators/src/main/AndroidManifest.xml b/operators/src/main/AndroidManifest.xml index b8ab777d..b1ee20bc 100644 --- a/operators/src/main/AndroidManifest.xml +++ b/operators/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:android="http://schemas.android.com/apk/res/android"> { - return flowOf() + return flowOf(7, 12, 4, 8, 11, 5, 7, 16, 99, 1) + .map { it * 5 } + .filter { it > 20 } + .filter { it % 2 != 0 } + .map { "$it won" } + .take(3) } /** @@ -29,7 +45,29 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + return (1..21).asFlow() + .flatMapConcat { + flow { + 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 +76,15 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + return flowOf( + "Red", + "Green", + "Blue", + "Black", + "White" + ).zip(flowOf("Circle", "Square", "Triangle")) { color, shape -> + color to shape + } } /** @@ -48,6 +94,9 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .catch { if (it is IllegalArgumentException) emit(-1) else throw it } + .onCompletion { sampleRepository.completed() } } -} \ No newline at end of file +} + diff --git a/operators/src/main/java/otus/homework/flow/SampleRepository.kt b/operators/src/main/java/otus/homework/flow/SampleRepository.kt index a16726e6..dd366a97 100644 --- a/operators/src/main/java/otus/homework/flow/SampleRepository.kt +++ b/operators/src/main/java/otus/homework/flow/SampleRepository.kt @@ -1,6 +1,7 @@ package otus.homework.flow import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf interface SampleRepository {