Skip to content

Instantly share code, notes, and snippets.

@seanghay
Last active October 26, 2020 03:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seanghay/0fd991d7a823815500557fe043b052ce to your computer and use it in GitHub Desktop.
Save seanghay/0fd991d7a823815500557fe043b052ce to your computer and use it in GitHub Desktop.
ViewBinding Property Delegate with Android Lifecycle
import android.os.Looper
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.viewbinding.ViewBinding
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
inline fun <reified T : ViewBinding> AppCompatActivity.viewBinding(noinline initializer: (LayoutInflater) -> T) =
ViewBindingPropertyDelegate(this, initializer)
class ViewBindingPropertyDelegate<T : ViewBinding>(
private val activity: AppCompatActivity,
private val initializer: (LayoutInflater) -> T
) : ReadOnlyProperty<AppCompatActivity, T>, LifecycleObserver {
private var _value: T? = null
init {
activity.lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
@Suppress("Unused")
fun onCreate() {
if (_value == null) {
_value = initializer(activity.layoutInflater)
}
activity.setContentView(_value?.root!!)
activity.lifecycle.removeObserver(this)
}
override fun getValue(thisRef: AppCompatActivity, property: KProperty<*>): T {
if (_value == null) {
// This must be on the main thread only
if (Looper.myLooper() != Looper.getMainLooper()) {
throw IllegalThreadStateException("This cannot be called from other threads. It should be on the main thread only.")
}
_value = initializer(thisRef.layoutInflater)
}
return _value!!
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment