0.4.0
As of 14 December 2020, Kotlin synthetics is deprecated and no longer supported. So we migrate our codebase to using ViewBinding. As of why, there's a few problem for using Kotlin synthetics, such as:
- They expose a global namespace of ids that’s unrelated to the layout that’s actually inflated with no checks against invalid lookups
- They are Kotlin only
- They don’t expose nullability when views are only present in some configuration
- All together, these issues cause the API to increase number of crashes for Android apps
- Also Google is promoting modularisation but synthetic properties don’t work cross-module
Since version 0.3.3
we migrate to viewBinding, so how do we migrate our code? Let's just start simple by enabling viewBinding in our app build.gradle
:
// we don't use this anymore
// apply plugin: 'kotlin-android-extensions'
android {
// Add this
buildFeatures {
viewBinding true
}
}
Activity and Fragment¶
When using this codebase, use DevActivity
and DevFragment
. For example, assume we have class named SampleActivity
with its' layout file named activity_sample.xml
. so how do we define that now using viewBinding, let's take a look:
// Now you need to add binding between < and >
class SampleActivity : DevActivity<ActivitySampleBinding>() {
// We no longer use it anymore, cause we will use binding
// override val layoutResource = R.layout.activity_sample
// Other override methods
override fun initAction(){}
override fun initData(){}
override fun initObserver(){}
override fun initUI(){}
}
Now, onto how we call our View
. Just add binding before View
id:
// with Kotlin synthetics
tvName.text = "your name"
// with viewBinding
binding.tvName.text = "your name"
RecyclerView ViewHolder and Adapter¶
For ViewHolder, now the parameter constructor it's not a View
anymore but layout binding:
// No longer supported
class SampleHolder(itemView : View) : DevItemViewHolder<Sample>(itemView)
// This is the way
// Add private val before the variable name and change it to the layout binding
class SampleHolder(private val binding : ItemSampleBinding) DevItemViewHolder<Sample>(binding)
Inside the ViewHolder class, call the View
by adding binding before its' id:
binding.tvName.text = "the user name"
Henceforth, for Adapter... no need to define the layout resource id in getResourceLayout
method. Change ViewHolder initialization in onCreateViewHolder
method:
override fun onCreateViewHolder(parent : ViewGroup, viewType : Int) =
SampleHolder(ItemUserBinding.inflate(getLayoutInflater(parent)))