From 63eb7b7ea888a7536039065ccf561b4cdee20a72 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 17 Jun 2021 12:54:06 +0600 Subject: [PATCH 1/4] start 0.5.12 --- CHANGELOG.md | 2 ++ gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d9502cc327..663061f3827 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## 0.5.12 + ## 0.5.11 * `Repos`: diff --git a/gradle.properties b/gradle.properties index 29762518c81..f6220a8c7ae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -45,5 +45,5 @@ dokka_version=1.4.32 # Project data group=dev.inmo -version=0.5.11 -android_code_version=52 +version=0.5.12 +android_code_version=53 From e715772dbf71546cf0a47c89f9f56d9ac1743b5e Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 17 Jun 2021 13:39:02 +0600 Subject: [PATCH 2/4] fill changes --- CHANGELOG.md | 8 +++++ android/recyclerview/build.gradle | 1 + .../recyclerview/RecyclerViewAdapter.kt | 16 ++++++++- .../StateFlowBasedRecyclerViewAdapter.kt | 33 +++++++++++++++++++ .../inmo/micro_utils/common/Annotations.kt | 2 +- .../inmo/micro_utils/common/ViewVisibility.kt | 4 +-- 6 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 663061f3827..7cb0d97306a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## 0.5.12 +* `Common`: + * `Android` + * Extension `View#changeVisibility` has been fixed +* `Android` + * `RecyclerView` + * Default adapter got `dataCountFlow` property + * New subtype of adapter based on `StateFlow`: `StateFlowBasedRecyclerViewAdapter` + ## 0.5.11 * `Repos`: diff --git a/android/recyclerview/build.gradle b/android/recyclerview/build.gradle index e0ca77546ee..1357ac98f51 100644 --- a/android/recyclerview/build.gradle +++ b/android/recyclerview/build.gradle @@ -11,6 +11,7 @@ kotlin { commonMain { dependencies { api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" + api project(":micro_utils.common") } } androidMain { diff --git a/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/RecyclerViewAdapter.kt b/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/RecyclerViewAdapter.kt index a5dc0e93450..b314ce2a3dd 100644 --- a/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/RecyclerViewAdapter.kt +++ b/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/RecyclerViewAdapter.kt @@ -3,11 +3,19 @@ package dev.inmo.micro_utils.android.recyclerview import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import kotlinx.coroutines.flow.* abstract class RecyclerViewAdapter: RecyclerView.Adapter>() { protected abstract val data: List + private val _dataCountState by lazy { + MutableStateFlow(data.size) + } + val dataCountState: StateFlow by lazy { + _dataCountState.asStateFlow() + } + var emptyView: View? = null set(value) { field = value @@ -19,31 +27,37 @@ abstract class RecyclerViewAdapter: RecyclerView.Adapter: RecyclerView.Adapter( + listeningScope: CoroutineScope, + dataState: StateFlow> +) : RecyclerViewAdapter() { + override var data: List = emptyList() + + init { + dataState.onEach { + val diff = Diff(data, it) + data = it + withContext(Dispatchers.Main) { + diff.removed.forEach { + notifyItemRemoved(it.index) + } + diff.replaced.forEach { (from, to) -> + notifyItemMoved(from.index, to.index) + } + diff.added.forEach { + notifyItemInserted(it.index) + } + } + }.launchIn(listeningScope) + } +} diff --git a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Annotations.kt b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Annotations.kt index 7873443768c..11eb33e07f5 100644 --- a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Annotations.kt +++ b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Annotations.kt @@ -16,7 +16,7 @@ package dev.inmo.micro_utils.common AnnotationTarget.TYPEALIAS, AnnotationTarget.TYPE_PARAMETER ) -annotation class PreviewFeature +annotation class PreviewFeature(val message: String = "It is possible, that behaviour of this thing will be changed or removed in future releases") @RequiresOptIn( "This thing is marked as warned. See message of warn to get more info", diff --git a/common/src/main/kotlin/dev/inmo/micro_utils/common/ViewVisibility.kt b/common/src/main/kotlin/dev/inmo/micro_utils/common/ViewVisibility.kt index 5c842f98883..ff636008564 100644 --- a/common/src/main/kotlin/dev/inmo/micro_utils/common/ViewVisibility.kt +++ b/common/src/main/kotlin/dev/inmo/micro_utils/common/ViewVisibility.kt @@ -36,12 +36,12 @@ fun View.toggleVisibility(goneOnHide: Boolean = true) { fun View.changeVisibility(show: Boolean = !isShown, goneOnHide: Boolean = true) { if (show) { + show() + } else { if (goneOnHide) { gone() } else { hide() } - } else { - show() } } From 6d999be590497413dd0ca212ece74f75155f6296 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 17 Jun 2021 13:45:19 +0600 Subject: [PATCH 3/4] small improvement in StateFlowBasedRecyclerViewAdapter --- .../StateFlowBasedRecyclerViewAdapter.kt | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt b/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt index d13141c006d..1d2ec68ed90 100644 --- a/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt +++ b/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt @@ -15,16 +15,29 @@ abstract class StateFlowBasedRecyclerViewAdapter( init { dataState.onEach { - val diff = Diff(data, it) + val diffForRemoves = Diff(data, it) + val removedIndexes = diffForRemoves.removed.map { it.index } + val leftRemove = removedIndexes.toMutableList() + data = data.filterIndexed { i, _ -> + if (i in leftRemove) { + leftRemove.remove(i) + true + } else { + false + } + } + withContext(Dispatchers.Main) { + removedIndexes.sortedDescending().forEach { + notifyItemRemoved(it) + } + } + val diffAddsAndReplaces = Diff(data, it) data = it withContext(Dispatchers.Main) { - diff.removed.forEach { - notifyItemRemoved(it.index) - } - diff.replaced.forEach { (from, to) -> + diffAddsAndReplaces.replaced.forEach { (from, to) -> notifyItemMoved(from.index, to.index) } - diff.added.forEach { + diffAddsAndReplaces.added.forEach { notifyItemInserted(it.index) } } From 1c86f3f4bf167f95dace29bea5c23b0eb463d1ef Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 17 Jun 2021 13:46:22 +0600 Subject: [PATCH 4/4] wrap with trycatch StateFlowBasedRecyclerViewAdapter listener --- .../StateFlowBasedRecyclerViewAdapter.kt | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt b/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt index 1d2ec68ed90..e7fa984741b 100644 --- a/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt +++ b/android/recyclerview/src/main/kotlin/dev/inmo/micro_utils/android/recyclerview/StateFlowBasedRecyclerViewAdapter.kt @@ -15,31 +15,35 @@ abstract class StateFlowBasedRecyclerViewAdapter( init { dataState.onEach { - val diffForRemoves = Diff(data, it) - val removedIndexes = diffForRemoves.removed.map { it.index } - val leftRemove = removedIndexes.toMutableList() - data = data.filterIndexed { i, _ -> - if (i in leftRemove) { - leftRemove.remove(i) - true - } else { - false + try { + val diffForRemoves = Diff(data, it) + val removedIndexes = diffForRemoves.removed.map { it.index } + val leftRemove = removedIndexes.toMutableList() + data = data.filterIndexed { i, _ -> + if (i in leftRemove) { + leftRemove.remove(i) + true + } else { + false + } } - } - withContext(Dispatchers.Main) { - removedIndexes.sortedDescending().forEach { - notifyItemRemoved(it) + withContext(Dispatchers.Main) { + removedIndexes.sortedDescending().forEach { + notifyItemRemoved(it) + } } - } - val diffAddsAndReplaces = Diff(data, it) - data = it - withContext(Dispatchers.Main) { - diffAddsAndReplaces.replaced.forEach { (from, to) -> - notifyItemMoved(from.index, to.index) - } - diffAddsAndReplaces.added.forEach { - notifyItemInserted(it.index) + val diffAddsAndReplaces = Diff(data, it) + data = it + withContext(Dispatchers.Main) { + diffAddsAndReplaces.replaced.forEach { (from, to) -> + notifyItemMoved(from.index, to.index) + } + diffAddsAndReplaces.added.forEach { + notifyItemInserted(it.index) + } } + } catch (e: Throwable) { + // currently do nothing } }.launchIn(listeningScope) }