Add fragment arguments utils

This commit is contained in:
Kirill Nayduik 2021-08-19 16:12:28 +12:00
parent 3c1342aad8
commit addd51c0ff
3 changed files with 70 additions and 0 deletions

View File

@ -2,6 +2,7 @@ apply from: "../android-configs/lib-config.gradle"
dependencies {
implementation "androidx.recyclerview:recyclerview"
implementation "androidx.fragment:fragment-ktx"
implementation project(path: ':logging')
constraints {
@ -10,5 +11,11 @@ dependencies {
require '1.0.0'
}
}
implementation("androidx.fragment:fragment-ktx") {
version {
require '1.2.1'
}
}
}
}

View File

@ -0,0 +1,38 @@
package ru.touchin.extensions
import android.os.Bundle
import android.os.Parcelable
import androidx.fragment.app.Fragment
import ru.touchin.utils.BundleExtractorDelegate
import kotlin.properties.ReadWriteProperty
inline fun <reified T> Fragment.args(
key: String? = null,
defaultValue: T? = null
): ReadWriteProperty<Fragment, T> {
return BundleExtractorDelegate { thisRef, property ->
val bundleKey = key ?: property.name
extractFromBundle(thisRef.arguments, bundleKey, defaultValue)
}
}
fun <T : Fragment> T.withArgs(receiver: Bundle.() -> Unit): T {
arguments = Bundle().apply(receiver)
return this
}
fun <T : Fragment> T.withParcelable(key: String, parcelable: Parcelable): T = withArgs {
putParcelable(key, parcelable)
}
inline fun <reified T> extractFromBundle(
bundle: Bundle?,
key: String? = null,
defaultValue: T? = null
): T {
val result = bundle?.get(key) ?: defaultValue
if (result != null && result !is T) {
throw ClassCastException("Property for $key has different class type")
}
return result as T
}

View File

@ -0,0 +1,25 @@
package ru.touchin.utils
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class BundleExtractorDelegate<R, T>(private val initializer: (R, KProperty<*>) -> T) : ReadWriteProperty<R, T> {
private object EMPTY
private var value: Any? = EMPTY
override fun setValue(thisRef: R, property: KProperty<*>, value: T) {
this.value = value
}
override fun getValue(thisRef: R, property: KProperty<*>): T {
if (value == EMPTY) {
value = initializer(thisRef, property)
}
@Suppress("UNCHECKED_CAST")
return value as T
}
}