你好!我叫基里尔·罗佐夫(Kirill Rozov)。我是电报频道Android Broadcast的作者。我非常喜欢Kotlin,并且我喜欢使用其功能来简化开发。当他们开始在一个新的Android项目上使用视图绑定时,我最近遇到了这个问题。

该功能出现在Android Studio 3.6中,但实际上它并不是全新的,而是Android Data Binding的轻量级版本。为什么会有这么多并发症?问题是速度-许多开发人员Android Data Binding
仅用于生成带有View链接的代码,而忽略了其他库功能。为加快代码生成速度,创建了View Binding
。但是,使用它的标准方法是复制要删除的代码。
使用视图绑定的标准方法
让我们使用Fragment示例查看视图绑定。我们有一个具有名称的布局资源profile.xml
(其内容无关紧要)。如果我们要使用ViewBinding,那么在标准版本中,它将如下所示:
class ProfileFragment : Fragment(R.layout.profile) {
private var viewBinding: ProfileBinding? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding = ProfileBinding.bind(view)
}
override fun onDestroyView() {
super.onDestroyView()
viewBinding = null
}
}
这里有几个问题:
- 很多额外的代码
- : Fragment
- Property
viewBinding
nullable .
C Kotlin
Kotlin Delegated Property
property Kotlin . , ViewBinding
. , ViewBinding
:
class FragmentViewBindingProperty<T : ViewBinding>(
private val viewBinder: ViewBinder<T>
) : ReadOnlyProperty<Fragment, T> {
internal var viewBinding: T? = null
private val lifecycleObserver = BindingLifecycleObserver()
@MainThread
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
checkIsMainThread()
this.viewBinding?.let { return it }
val view = thisRef.requireView()
thisRef.viewLifecycleOwner.lifecycle.addObserver(lifecycleObserver)
return viewBinder.bind(view).also { vb -> this.viewBinding = vb }
}
private inner class BindingLifecycleObserver : DefaultLifecycleObserver {
@MainThread
override fun onDestroy(owner: LifecycleOwner) {
owner.lifecycle.removeObserver(this)
viewBinding = null
}
}
}
-, :
inline fun <reified T : ViewBinding> Fragment.viewBinding(): ReadOnlyProperty<Fragment, T> {
return FragmentViewBindingProperty(DefaultViewBinder(T::class.java))
}
:
class ProfileFragment() : Fragment(R.layout.profile) {
private val viewBinding: ProfileBinding by viewBinding()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}
, , . ?
, - ...
- View :
class ProfileFragment() : Fragment(R.layout.profile) {
private val viewBinding: ProfileBinding by viewBinding()
override fun onDestroyView() {
super.onDestroyView()
}
}
, ViewBinding property . super.onDestroyView()
. Fragment.viewLifecycleOwner
.
ON_DESTROY
Fragment.viewLifecycleOwner
Fragment.onDestroyView()
, FragmentViewBindingProperty
, . . , Handler
:
class FragmentViewBindingProperty<T : ViewBinding>(...) : ReadOnlyProperty<Fragment, T> {
internal var viewBinding: T? = null
private inner class BindingLifecycleObserver : DefaultLifecycleObserver {
private val mainHandler = Handler(Looper.getMainLooper())
@MainThread
override fun onDestroy(owner: LifecycleOwner) {
owner.lifecycle.removeObserver(this)
mainHandler.post { viewBinding = null }
}
}
}
.