Kotlin synthetic in Adapter or ViewHolder
KotlinKotlin Android-ExtensionsKotlin Problem Overview
I am new in kotlin. I have found and tried to use synthetic method instead of annoying method findViewById
in my Activity
class, but I have found "If we want to call the synthetic properties on View (useful in adapter classes), we should also import kotlinx.android.synthetic.main.view.*." But I can't figure out how it exactly works? Is there any examples?
Kotlin Solutions
Solution 1 - Kotlin
Simple example from https://github.com/antoniolg/Kotlin-for-Android-Developers
import kotlinx.android.synthetic.item_forecast.view.*
class ForecastListAdapter() : RecyclerView.Adapter<ForecastListAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bindForecast(forecast: Forecast) {
itemView.date.text = forecast.date.toDateString()
}
}
}
No need to write
val view = itemView.findViewById(R.id.date) as TextView
view.text = forecast.date.toDateString()
Just
itemView.date.text = forecast.date.toDateString()
Simple and effective!
Solution 2 - Kotlin
Kotling 1.1.4 out
Further information : https://antonioleiva.com/kotlin-android-extensions/
You need to enable Kotlin Android Extentions by adding this to your build.gradle:
apply plugin: 'org.jetbrains.kotlin.android.extensions'
androidExtensions {
experimental = true
}
Since this new version of Kotlin, the Android Extensions have incorporated some new interesting features: caches in any class (which interestingly includes ViewHolder)
Using it on a ViewHolder (or any custom class). Note that this class should implement LayoutContainer
interface:
class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView),
LayoutContainer {
fun bind(title: String) {
itemTitle.text = "Hello Kotlin!"
}
}
Solution 3 - Kotlin
You need
import kotlinx.android.synthetic.row_wall.view.*
And later something along the lines of:
convertView.titleText.text = item.title
The point is that the view.* introduces extensions to the View class.
Solution 4 - Kotlin
Try
class CustomViewModel(val baseView: View) {
val firstName = baseView.firstName
val lastName = baseView.lastName
}
View object exposes the views ref:https://discuss.kotlinlang.org/t/unable-to-use-kotlin-android-extension-in-adapter-class/2890
Solution 5 - Kotlin
If you are using the latest version l;.you don't have to add experimental = true to it.
in Project level Gradle
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21'
And in app level Gradle
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' //These should be on the top of file.
and in dependencies..
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21'
and import below as
import kotlinx.android.synthetic.main.your_layout_file_name.view.*
and example
import kotlinx.android.synthetic.main.item_animal.view.*
class AnimalVH(parent: ViewGroup, layoutID: Int) : BaseViewHolder<Animal>(parent, layoutID) {
override fun bindData(animal: Animal) {
itemView.tv_animal.text = animal.title
}
}
where BaseViewHolder is
abstract class BaseViewHolder<T>(parent: ViewGroup, layoutID: Int) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context).inflate(layoutID, parent, false)
) {
abstract fun bindData(model: T)
}
Solution 6 - Kotlin
It means you have to place this line at the beginning of your source file:
import kotlinx.android.synthetic.main.view.*
So now instead of, for example, findView(R.id.textView) as TextView
you would write just textView
. The latter is a synthetic extension property located in the package kotlinx.android.synthetic.main.view
, that's why you have to import everything from it.
There's a tutorial on the official site, take a look.
Solution 7 - Kotlin
FYI: Data binding is recommended over synthetic for view lookups.
Comment from a DA for Android from Google on Reddit
> Hey! Developer Advocate for Android at Google here! > > I wanted to add a bit of background here. Kotlin Extensions with > synthetic views was never intentionally “recommended” though that > shouldn’t be taken as a recommendation to not use them. If they're > working for you please feel free to continue using them in your app! > > We’ve been shifting away from them (e.g. we don’t teach them in the > Udacity course) because they expose a global namespace of ids that’s > unrelated to the layout that’s actually inflated with no checks > against invalid lookups, are Kotlin only, and 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. > > On the other hand, they do offer a lightweight API that can help > simplify view lookups. In this space it's also worth taking a look at > Data Binding which also does automatic view lookups - as well as > integrates with LiveData to automatically update your views as data > changes. > > Today, there's a few options in this space that work: > > Data Binding is the recommendation for view lookup as well as binding, > but it does add a bit of overhead when compared to Android Kotlin > Extensions. It's worth taking a look to see if this is a good fit for > your app. Data Binding also allows you to observe LiveData to bind > views automatically when data changes. Compared to Kotlin Extensions, > it adds compile time checking of view lookups and type safety. Android > Kotlin Extensions is not officially recommended (which is not the same > as recommendation against). It does come with the issues mentioned > above, so for our code we're not using them. Butter Knife is another > solution that is extremely popular and works for both Kotlin and the > Java Programming Language. Reading through the comments here there's a > lot of developers that are having great luck with Kotlin Extensions. > That's great - and something we'll keep in mind as we look at ways to > continue improving our APIs. If you haven't taken a look at Data > Binding, definitely give it a shot. > > As an aside, our internal code style guide is not intended to be > directly applied outside of our codebase. For example, we use > mPrefixVariables, but there's no reason that every app should follow > that style.