背景
把 ViewBinding 集成在项目后,每次都需要在 Activity 或者 Fragment 中声明ViewBinding 的模板代码, 有些小伙伴会选择把模板代码放在相关的基类完成,通过反射完成, 但是对于有代码洁癖的我来说,这点还是不太好接受, 虽然在项目中用过,但是一直在心里想找一个更优雅的方式,正好最近在看 kotlin 的代理, 把 by 的原理看了下,恰好其中的 lazy 就是其一个典型的应用,于是心里就想,应该也能利用这样的思想去优化一下 ViewBinding 的使用, 于是就有了下面的内容
声明 AppCompatActivity 的 扩展方法
inline fun <reified BindingT : ViewBinding> AppCompatActivity.viewBindings(
crossinline bind: (View) -> BindingT
) = object : Lazy<BindingT> {
private var initialized: BindingT? = null
override val value: BindingT
get() = initialized ?: bind(
findViewById<ViewGroup>(android.R.id.content).getChildAt(0)
).also {
initialized = it
}
override fun isInitialized() = initialized != null
}
使用:xxxAppCompatActivity.kt 中,binding by viewBindings(xxxActivityBinding::bind)
声明 Fragment 的 扩展方法
inline fun <reified BindingT : ViewBinding> Fragment.viewBindings(
crossinline bind: (View) -> BindingT
) = object : Lazy<BindingT> {
private var initialized: BindingT? = null
private val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
initialized = null
}
}
override val value: BindingT
get() = initialized ?: bind(requireView()).also {
viewLifecycleOwner.lifecycle.addObserver(observer)
initialized = it
}
override fun isInitialized() = initialized != null
}
使用:xxxFragment.kt 中,`binding by viewBindings(xxxFragmentBinding::bind)