Halo! Nama saya Kirill Rozov. Saya penulis saluran Telegram Android Broadcast . Saya sangat menyukai Kotlin dan saya suka menggunakan fitur-fiturnya untuk menyederhanakan pengembangan. Baru-baru ini saya menghadapi masalah ini ketika mereka mulai menggunakan View Binding pada proyek Android baru .

Fitur ini muncul di Android Studio 3.6, tetapi sebenarnya itu tidak sepenuhnya baru, tetapi versi ringan dari Android Data Binding . Kenapa banyak sekali komplikasi? Masalahnya adalah kecepatan - banyak pengembang Android Data Binding
hanya digunakan untuk menghasilkan kode dengan tautan ke Lihat dan mengabaikan fitur perpustakaan lainnya. Untuk mempercepat pembuatan kode, dibuat View Binding
. Namun, cara standar untuk mengatasinya adalah dengan menggandakan kode yang ingin Anda singkirkan.
Cara standar untuk bekerja dengan View Binding
Mari kita lihat View Binding menggunakan contoh Fragment. Kami memiliki sumber daya tata letak dengan nama profile.xml
(isinya tidak masalah). Jika kita ingin menggunakan ViewBinding, maka dalam versi standar akan terlihat seperti ini:
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
}
}
Ada beberapa masalah di sini:
- Banyak kode tambahan
- : 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 }
}
}
}
.