mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-10-30 03:30:19 +00:00
update dependencies
This commit is contained in:
1
common/src/androidMain/AndroidManifest.xml
Normal file
1
common/src/androidMain/AndroidManifest.xml
Normal file
@@ -0,0 +1 @@
|
||||
<manifest package="dev.inmo.micro_utils.common"/>
|
||||
@@ -0,0 +1,76 @@
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import androidx.fragment.app.Fragment
|
||||
import java.io.Serializable
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
object ArgumentPropertyNullableDelegate {
|
||||
operator fun <T: Any> getValue(thisRef: Fragment, property: KProperty<*>): T? {
|
||||
val arguments = thisRef.arguments ?: return null
|
||||
val key = property.name
|
||||
return when (property.getter.returnType.classifier) {
|
||||
// Scalars
|
||||
String::class -> arguments.getString(key)
|
||||
Boolean::class -> arguments.getBoolean(key)
|
||||
Byte::class -> arguments.getByte(key)
|
||||
Char::class -> arguments.getChar(key)
|
||||
Double::class -> arguments.getDouble(key)
|
||||
Float::class -> arguments.getFloat(key)
|
||||
Int::class -> arguments.getInt(key)
|
||||
Long::class -> arguments.getLong(key)
|
||||
Short::class -> arguments.getShort(key)
|
||||
|
||||
// References
|
||||
Bundle::class -> arguments.getBundle(key)
|
||||
CharSequence::class -> arguments.getCharSequence(key)
|
||||
Parcelable::class -> arguments.getParcelable(key)
|
||||
|
||||
// Scalar arrays
|
||||
BooleanArray::class -> arguments.getBooleanArray(key)
|
||||
ByteArray::class -> arguments.getByteArray(key)
|
||||
CharArray::class -> arguments.getCharArray(key)
|
||||
DoubleArray::class -> arguments.getDoubleArray(key)
|
||||
FloatArray::class -> arguments.getFloatArray(key)
|
||||
IntArray::class -> arguments.getIntArray(key)
|
||||
LongArray::class -> arguments.getLongArray(key)
|
||||
ShortArray::class -> arguments.getShortArray(key)
|
||||
Array::class -> {
|
||||
val componentType = property.returnType.classifier ?.javaClass ?.componentType!!
|
||||
@Suppress("UNCHECKED_CAST") // Checked by reflection.
|
||||
when {
|
||||
Parcelable::class.java.isAssignableFrom(componentType) -> {
|
||||
arguments.getParcelableArray(key)
|
||||
}
|
||||
String::class.java.isAssignableFrom(componentType) -> {
|
||||
arguments.getStringArray(key)
|
||||
}
|
||||
CharSequence::class.java.isAssignableFrom(componentType) -> {
|
||||
arguments.getCharSequenceArray(key)
|
||||
}
|
||||
Serializable::class.java.isAssignableFrom(componentType) -> {
|
||||
arguments.getSerializable(key)
|
||||
}
|
||||
else -> {
|
||||
val valueType = componentType.canonicalName
|
||||
throw IllegalArgumentException(
|
||||
"Illegal value array type $valueType for key \"$key\""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Serializable::class -> arguments.getSerializable(key)
|
||||
else -> null
|
||||
} as? T
|
||||
}
|
||||
}
|
||||
|
||||
object ArgumentPropertyNonNullableDelegate {
|
||||
operator fun <T: Any> getValue(thisRef: Fragment, property: KProperty<*>): T {
|
||||
return ArgumentPropertyNullableDelegate.getValue<T>(thisRef, property)!!
|
||||
}
|
||||
}
|
||||
|
||||
fun argumentOrNull() = ArgumentPropertyNullableDelegate
|
||||
fun argumentOrThrow() = ArgumentPropertyNonNullableDelegate
|
||||
@@ -0,0 +1,13 @@
|
||||
@file:Suppress("NOTHING_TO_INLINE")
|
||||
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
import android.content.res.Resources
|
||||
|
||||
inline fun Resources.getSp(
|
||||
resId: Int
|
||||
) = getDimension(resId) / displayMetrics.scaledDensity
|
||||
|
||||
inline fun Resources.getDp(
|
||||
resId: Int
|
||||
) = getDimension(resId) * displayMetrics.density
|
||||
@@ -0,0 +1,140 @@
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.Animation
|
||||
import android.view.animation.Transformation
|
||||
|
||||
private fun View.performExpand(
|
||||
duration: Long = 500,
|
||||
targetWidth: Int = ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
targetHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
onMeasured: View.() -> Unit,
|
||||
onPerformAnimation: View.(interpolatedTime: Float, t: Transformation?) -> Unit
|
||||
) {
|
||||
measure(targetWidth, targetHeight)
|
||||
onMeasured()
|
||||
show()
|
||||
val a: Animation = object : Animation() {
|
||||
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
|
||||
super.applyTransformation(interpolatedTime, t)
|
||||
onPerformAnimation(interpolatedTime, t)
|
||||
requestLayout()
|
||||
}
|
||||
|
||||
override fun willChangeBounds(): Boolean = true
|
||||
}
|
||||
|
||||
a.duration = duration
|
||||
startAnimation(a)
|
||||
}
|
||||
|
||||
private fun View.performCollapse(
|
||||
duration: Long = 500,
|
||||
onPerformAnimation: View.(interpolatedTime: Float, t: Transformation?) -> Unit
|
||||
) {
|
||||
val a: Animation = object : Animation() {
|
||||
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
|
||||
if (interpolatedTime == 1f) {
|
||||
gone()
|
||||
} else {
|
||||
onPerformAnimation(interpolatedTime, t)
|
||||
requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
override fun willChangeBounds(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
a.duration = duration
|
||||
|
||||
startAnimation(a)
|
||||
}
|
||||
|
||||
@PreviewFeature
|
||||
fun View.expand(
|
||||
duration: Long = 500,
|
||||
targetWidth: Int = ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
targetHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
) {
|
||||
var measuredHeight = 0
|
||||
performExpand(
|
||||
duration,
|
||||
targetWidth,
|
||||
targetHeight,
|
||||
{
|
||||
measuredHeight = this.measuredHeight
|
||||
}
|
||||
) { interpolatedTime, _ ->
|
||||
layoutParams.height = if (interpolatedTime == 1f) targetHeight else (measuredHeight * interpolatedTime).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewFeature
|
||||
fun View.expandHorizontally(
|
||||
duration: Long = 500,
|
||||
targetWidth: Int = ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
targetHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
) {
|
||||
var measuredWidth = 0
|
||||
performExpand(
|
||||
duration,
|
||||
targetWidth,
|
||||
targetHeight,
|
||||
{
|
||||
measuredWidth = this.measuredWidth
|
||||
}
|
||||
) { interpolatedTime, _ ->
|
||||
layoutParams.width = if (interpolatedTime == 1f) targetWidth else (measuredWidth * interpolatedTime).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewFeature
|
||||
fun View.collapse(duration: Long = 500) {
|
||||
val initialHeight: Int = measuredHeight
|
||||
performCollapse(duration) { interpolatedTime, _ ->
|
||||
layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewFeature
|
||||
fun View.collapseHorizontally(duration: Long = 500) {
|
||||
val initialWidth: Int = measuredWidth
|
||||
performCollapse(duration) { interpolatedTime, _ ->
|
||||
layoutParams.width = initialWidth - (initialWidth * interpolatedTime).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true in case of expanding
|
||||
*/
|
||||
@PreviewFeature
|
||||
fun View.toggleExpandHorizontallyState(duration: Long = 500): Boolean = if (isCollapsed) {
|
||||
expandHorizontally(duration)
|
||||
true
|
||||
} else {
|
||||
collapseHorizontally(duration)
|
||||
false
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.children
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
fun findViewsByTag(viewGroup: ViewGroup, tag: Any?): List<View> {
|
||||
return viewGroup.children.flatMap {
|
||||
findViewsByTag(it, tag)
|
||||
}.toList()
|
||||
}
|
||||
|
||||
fun findViewsByTag(viewGroup: ViewGroup, key: Int, tag: Any?): List<View> {
|
||||
return viewGroup.children.flatMap {
|
||||
findViewsByTag(it, key, tag)
|
||||
}.toList()
|
||||
}
|
||||
|
||||
fun findViewsByTag(view: View, tag: Any?): List<View> {
|
||||
val result = mutableListOf<View>()
|
||||
if (view.tag == tag) {
|
||||
result.add(view)
|
||||
}
|
||||
if (view is ViewGroup) {
|
||||
result.addAll(findViewsByTag(view, tag))
|
||||
}
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
fun findViewsByTag(view: View, key: Int, tag: Any?): List<View> {
|
||||
val result = mutableListOf<View>()
|
||||
if (view.getTag(key) == tag) {
|
||||
result.add(view)
|
||||
}
|
||||
if (view is ViewGroup) {
|
||||
result.addAll(findViewsByTag(view, key, tag))
|
||||
}
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
fun Activity.findViewsByTag(tag: Any?) = rootView ?.let {
|
||||
findViewsByTag(it, tag)
|
||||
}
|
||||
|
||||
fun Activity.findViewsByTag(key: Int, tag: Any?) = rootView ?.let {
|
||||
findViewsByTag(it, key, tag)
|
||||
}
|
||||
|
||||
fun Fragment.findViewsByTag(tag: Any?) = view ?.let {
|
||||
findViewsByTag(it, tag)
|
||||
}
|
||||
|
||||
fun Fragment.findViewsByTag(key: Int, tag: Any?) = view ?.let {
|
||||
findViewsByTag(it, key, tag)
|
||||
}
|
||||
|
||||
fun Fragment.findViewsByTagInActivity(tag: Any?) = activity ?.findViewsByTag(tag)
|
||||
|
||||
fun Fragment.findViewsByTagInActivity(key: Int, tag: Any?) = activity ?.findViewsByTag(key, tag)
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "SimplifiableCall")
|
||||
inline fun <T, R> Iterable<T>.mapNotNullA(transform: (T) -> R?): List<R> = map(transform).filter { it != null } as List<R>
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "SimplifiableCall")
|
||||
inline fun <T, R> Array<T>.mapNotNullA(mapper: (T) -> R?): List<R> = map(mapper).filter { it != null } as List<R>
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
|
||||
val Activity.rootView: View?
|
||||
get() = findViewById<View?>(android.R.id.content) ?.rootView ?: window.decorView.findViewById<View?>(android.R.id.content) ?.rootView
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
@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()
|
||||
}
|
||||
}
|
||||
|
||||
fun View.changeVisibility(show: Boolean = !isShown, goneOnHide: Boolean = true) {
|
||||
if (show) {
|
||||
show()
|
||||
} else {
|
||||
if (goneOnHide) {
|
||||
gone()
|
||||
} else {
|
||||
hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user