diff --git a/CHANGELOG.md b/CHANGELOG.md index cb594bcf8bd..96ee10d565d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ * `Android` * `Alerts` * Project has been created +* `Common` + * Annotation `PreviewFeature` has been added + * `Android` + * Added tools to work with visibility in more comfortable way + * Added tools to work with disabled/enabled state in more comfortable way + * Added tools to work with expanded/collapsed state in more comfortable way (in preview mode) ## 0.4.4 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 new file mode 100644 index 00000000000..a05f4360397 --- /dev/null +++ b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Annotations.kt @@ -0,0 +1,19 @@ +package dev.inmo.micro_utils.common + +@RequiresOptIn( + "It is possible, that behaviour of this thing will be changed or removed in future releases", + RequiresOptIn.Level.WARNING +) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.PROPERTY, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPE, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.TYPE_PARAMETER +) +annotation class PreviewFeature diff --git a/common/src/main/kotlin/dev/inmo/micro_utils/common/ExpandCollapse.kt b/common/src/main/kotlin/dev/inmo/micro_utils/common/ExpandCollapse.kt new file mode 100644 index 00000000000..4fba2b56349 --- /dev/null +++ b/common/src/main/kotlin/dev/inmo/micro_utils/common/ExpandCollapse.kt @@ -0,0 +1,76 @@ +package dev.inmo.micro_utils.common + +import android.view.View +import android.view.ViewGroup +import android.view.animation.Animation +import android.view.animation.Transformation + +@PreviewFeature +fun View.expand( + duration: Long = 500, + targetWidth: Int = ViewGroup.LayoutParams.MATCH_PARENT, + targetHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT +) { + measure(targetWidth, targetHeight) + val measuredHeight: Int = measuredHeight + layoutParams.height = 0 + visibility = View.VISIBLE + val a: Animation = object : Animation() { + override fun applyTransformation(interpolatedTime: Float, t: Transformation?) { + super.applyTransformation(interpolatedTime, t) + layoutParams.height = if (interpolatedTime == 1f) targetHeight else (measuredHeight * interpolatedTime).toInt() + requestLayout() + } + + override fun willChangeBounds(): Boolean { + return true + } + } + + a.duration = duration + + startAnimation(a) +} + +@PreviewFeature +fun View.collapse(duration: Long = 500) { + val initialHeight: Int = measuredHeight + val a: Animation = object : Animation() { + override fun applyTransformation(interpolatedTime: Float, t: Transformation?) { + if (interpolatedTime == 1f) { + visibility = View.GONE + } else { + layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt() + requestLayout() + } + } + + override fun willChangeBounds(): Boolean { + return true + } + } + + a.duration = duration + + startAnimation(a) +} + +@PreviewFeature +inline val View.isCollapsed + get() = visibility == View.GONE + +@PreviewFeature +inline val View.isExpanded + get() = !isCollapsed + +/** + * @return true in case of expanding + */ +@PreviewFeature +fun View.toggleExpandState(duration: Long = 500): Boolean = if (isCollapsed) { + expand(duration) + true +} else { + collapse(duration) + false +} diff --git a/common/src/main/kotlin/dev/inmo/micro_utils/common/ViewDisable.kt b/common/src/main/kotlin/dev/inmo/micro_utils/common/ViewDisable.kt new file mode 100644 index 00000000000..59c8afe9a7e --- /dev/null +++ b/common/src/main/kotlin/dev/inmo/micro_utils/common/ViewDisable.kt @@ -0,0 +1,34 @@ +@file:Suppress("NOTHING_TO_INLINE", "unused") + +package dev.inmo.micro_utils.common + +import android.view.View +import android.view.ViewGroup + +inline val View.enabled + get() = isEnabled + +inline val View.disabled + get() = !enabled + +fun View.disable() { + if (this is ViewGroup) { + (0 until childCount).forEach { getChildAt(it).disable() } + } + isEnabled = false +} + +fun View.enable() { + if (this is ViewGroup) { + (0 until childCount).forEach { getChildAt(it).enable() } + } + isEnabled = true +} + +fun View.toggleEnabledState(enabled: Boolean) { + if (enabled) { + enable() + } else { + disable() + } +} 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 new file mode 100644 index 00000000000..3bdc1f3868a --- /dev/null +++ b/common/src/main/kotlin/dev/inmo/micro_utils/common/ViewVisibility.kt @@ -0,0 +1,35 @@ +@file:Suppress("NOTHING_TO_INLINE", "unused") + +package dev.inmo.micro_utils.common + +import android.view.View + +inline val View.gone + get() = visibility == View.GONE +inline fun View.gone() { + visibility = View.GONE +} + +inline val View.hidden + get() = visibility == View.INVISIBLE +inline fun View.hide() { + visibility = View.INVISIBLE +} + +inline val View.shown + get() = visibility == View.VISIBLE +inline fun View.show() { + visibility = View.VISIBLE +} + +fun View.toggleVisibility(goneOnHide: Boolean = true) { + if (isShown) { + if (goneOnHide) { + gone() + } else { + hide() + } + } else { + show() + } +}