مرحبا! اسمي كيريل روزوف. أنا مؤلف قناة Telegram Android Broadcast . أنا أحب Kotlin كثيرًا وأحب استخدام ميزاته لتبسيط التطوير. لقد واجهت هذه المشكلة مؤخرًا عندما بدأوا في استخدام View Binding في مشروع Android جديد .

ظهرت هذه الميزة في Android Studio 3.6 ، ولكنها في الواقع ليست جديدة تمامًا ، ولكنها نسخة خفيفة الوزن من Android Data Binding . لماذا الكثير من المضاعفات؟ كانت المشكلة تكمن في السرعة - حيث تم استخدام العديد من المطورين Android Data Binding
فقط لإنشاء تعليمات برمجية بروابط عرض وتجاهل ميزات المكتبة الأخرى. لتسريع إنشاء رمز ، تم إنشاؤه View Binding
. ومع ذلك ، فإن الطريقة القياسية للعمل معها هي تكرار التعليمات البرمجية التي تريد التخلص منها.
الطريقة القياسية للعمل مع View Binding
دعونا نلقي نظرة على عرض الربط باستخدام مثال التجزئة. لدينا مورد تخطيط باسم 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 }
}
}
}
.