background

After integrating the ViewBinding into the project, we need to declare the ViewBinding template code in the Activity or Fragment every time. Some friends will choose to complete the template code in the relevant base class, through reflection, but for me, who is a code cleanliness addict, This is not easy to accept, although I used it in the project, BUT I have been looking for a more elegant way. I happened to see Kotlin’s agent recently, and I happened to see the principle of by, and lazy is a typical application of it, so I thought, It should be possible to use this idea to optimize the use of ViewBinding as well, which leads to the following

Declare an extension method for 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 }Copy the code

Bindings by viewBindings(xxxActivityBinding::bind) can be found in xxxAppCompatActivity.

Declare extension methods for fragments

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 }Copy the code

Bindings by viewBindings(xxxFragmentBinding::bind) using: xxxFragmentbindings. Kt

Ending

Making the address