From aa9dfb4ab8160d7c6cd6c87aa82d81a5f88dfe7f Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 26 Sep 2022 00:47:32 +0600 Subject: [PATCH 1/3] start 0.12.16 --- CHANGELOG.md | 2 ++ gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89d11bb3aa0..9664e270945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## 0.12.16 + ## 0.12.15 * `Common`: diff --git a/gradle.properties b/gradle.properties index 3732f846fb0..81e464f4bb1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,5 +14,5 @@ crypto_js_version=4.1.1 # Project data group=dev.inmo -version=0.12.15 -android_code_version=154 +version=0.12.16 +android_code_version=155 From 9d95687d3cbb3b8e01203fbb201afc3469cce7a3 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 26 Sep 2022 01:02:12 +0600 Subject: [PATCH 2/3] FlowOnHierarchyChangeListener --- CHANGELOG.md | 5 ++ .../kotlin/FlowOnHierarchyChangeListener.kt | 50 +++++++++++++++++++ .../kotlin/RecursiveHierarchySubscriber.kt | 17 +++++++ 3 files changed, 72 insertions(+) create mode 100644 coroutines/src/main/kotlin/FlowOnHierarchyChangeListener.kt create mode 100644 coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 9664e270945..9aae3ae9c7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## 0.12.16 +* `Coroutines`: + * `Android`: + * Add class `FlowOnHierarchyChangeListener` + * Add `ViewGroup#setOnHierarchyChangeListenerRecursively(OnHierarchyChangeListener)` + ## 0.12.15 * `Common`: diff --git a/coroutines/src/main/kotlin/FlowOnHierarchyChangeListener.kt b/coroutines/src/main/kotlin/FlowOnHierarchyChangeListener.kt new file mode 100644 index 00000000000..f05056bcd9a --- /dev/null +++ b/coroutines/src/main/kotlin/FlowOnHierarchyChangeListener.kt @@ -0,0 +1,50 @@ +package dev.inmo.micro_utils.coroutines + +import android.view.View +import android.view.ViewGroup +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.asSharedFlow + +/** + * [kotlinx.coroutines.flow.Flow]-based [android.view.ViewGroup.OnHierarchyChangeListener] + * + * @param recursive If set, any call of [onChildViewAdded] will check if child [View] is [ViewGroup] and subscribe to this + * [ViewGroup] too + * @param [_onChildViewAdded] Internal [MutableSharedFlow] which will be used to pass data to [onChildViewAdded] flow + * @param [_onChildViewRemoved] Internal [MutableSharedFlow] which will be used to pass data to [onChildViewRemoved] flow + */ +class FlowOnHierarchyChangeListener( + private val recursive: Boolean = false, + private val _onChildViewAdded: MutableSharedFlow> = MutableSharedFlow(extraBufferCapacity = Int.MAX_VALUE), + private val _onChildViewRemoved: MutableSharedFlow> = MutableSharedFlow(extraBufferCapacity = Int.MAX_VALUE) +) : ViewGroup.OnHierarchyChangeListener { + val onChildViewAdded = _onChildViewAdded.asSharedFlow() + val onChildViewRemoved = _onChildViewRemoved.asSharedFlow() + + /** + * Will emit data into [onChildViewAdded] flow. If [recursive] is true and [child] is [ViewGroup] will also + * subscribe to [child] hierarchy changes. + * + * Due to the fact that this method is not suspendable, [FlowOnHierarchyChangeListener] will use + * [MutableSharedFlow.tryEmit] to send data into [_onChildViewAdded]. That is why its default extraBufferCapacity is + * [Int.MAX_VALUE] + */ + override fun onChildViewAdded(parent: View, child: View) { + _onChildViewAdded.tryEmit(parent to child) + + if (recursive && child is ViewGroup) { + child.setOnHierarchyChangeListener(this) + } + } + + /** + * Just emit data into [onChildViewRemoved] + * + * Due to the fact that this method is not suspendable, [FlowOnHierarchyChangeListener] will use + * [MutableSharedFlow.tryEmit] to send data into [_onChildViewRemoved]. That is why its default extraBufferCapacity is + * [Int.MAX_VALUE] + */ + override fun onChildViewRemoved(parent: View, child: View) { + _onChildViewRemoved.tryEmit(parent to child) + } +} diff --git a/coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt b/coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt new file mode 100644 index 00000000000..c991f8d50c8 --- /dev/null +++ b/coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt @@ -0,0 +1,17 @@ +package dev.inmo.micro_utils.coroutines + +import android.view.ViewGroup +import android.view.ViewGroup.OnHierarchyChangeListener + +/** + * Use [ViewGroup.setOnHierarchyChangeListener] recursively for all available [ViewGroup]s starting with [this]. + * This extension DO NOT guarantee that recursive subscription will happen after this method call + */ +fun ViewGroup.setOnHierarchyChangeListenerRecursively( + listener: OnHierarchyChangeListener +) { + setOnHierarchyChangeListener(listener) + (0 until childCount).forEach { + (getChildAt(it) as? ViewGroup) ?.setOnHierarchyChangeListener(listener) + } +} From de999e197fa11fbbed3c54977ce8cce127b157dc Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 26 Sep 2022 01:10:10 +0600 Subject: [PATCH 3/3] fix of setOnHierarchyChangeListenerRecursively --- coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt b/coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt index c991f8d50c8..4ed8a28841d 100644 --- a/coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt +++ b/coroutines/src/main/kotlin/RecursiveHierarchySubscriber.kt @@ -12,6 +12,6 @@ fun ViewGroup.setOnHierarchyChangeListenerRecursively( ) { setOnHierarchyChangeListener(listener) (0 until childCount).forEach { - (getChildAt(it) as? ViewGroup) ?.setOnHierarchyChangeListener(listener) + (getChildAt(it) as? ViewGroup) ?.setOnHierarchyChangeListenerRecursively(listener) } }