Pixelcat-App-Android/app/src/main/kotlin/at/connyduck/pixelcat/util/ViewBindingExtensions.kt

67 lines
2.3 KiB
Kotlin
Raw Normal View History

2020-06-12 15:44:45 +02:00
package at.connyduck.pixelcat.util
import android.view.LayoutInflater
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.viewbinding.ViewBinding
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
/**
* https://medium.com/@Zhuinden/simple-one-liner-viewbinding-in-fragments-and-activities-with-kotlin-961430c6c07c
*/
inline fun <T : ViewBinding> AppCompatActivity.viewBinding(
2020-06-12 19:58:15 +02:00
crossinline bindingInflater: (LayoutInflater) -> T
) = lazy(LazyThreadSafetyMode.NONE) {
bindingInflater(layoutInflater)
}
2020-06-12 15:44:45 +02:00
class FragmentViewBindingDelegate<T : ViewBinding>(
val fragment: Fragment,
val viewBindingFactory: (View) -> T
) : ReadOnlyProperty<Fragment, T> {
private var binding: T? = null
init {
2020-09-04 19:06:47 +02:00
fragment.lifecycle.addObserver(
object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
fragment.viewLifecycleOwnerLiveData.observe(
fragment
) { t ->
t?.lifecycle?.addObserver(
object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
binding = null
2020-09-04 19:06:47 +02:00
}
}
)
}
2020-09-04 19:06:47 +02:00
}
2020-06-12 15:44:45 +02:00
}
2020-09-04 19:06:47 +02:00
)
2020-06-12 15:44:45 +02:00
}
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
val binding = binding
if (binding != null) {
return binding
}
val lifecycle = fragment.viewLifecycleOwner.lifecycle
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.")
}
return viewBindingFactory(thisRef.requireView()).also { this@FragmentViewBindingDelegate.binding = it }
}
}
fun <T : ViewBinding> Fragment.viewBinding(viewBindingFactory: (View) -> T) =
2020-06-12 19:58:15 +02:00
FragmentViewBindingDelegate(this, viewBindingFactory)