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?

- 2,540
- 1
- 16
- 35
-
You can check this [blog](https://thedeveloperworldisyours.com/kotlin-android/kotlin-android-extensions-in-adapter/) or this [example](https://github.com/thedeveloperworldisyours/RoomAnko/blob/master/app/src/main/java/com/thedeveloperworldisyours/mytasks/task/TaskAdapter.kt) – Cabezas Oct 14 '18 at 16:51
7 Answers
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!

- 7,456
- 3
- 21
- 22
-
4ok, this might be a dumb question, but where does 'itemView' reference come from? – Saulo Aguiar Dec 17 '16 at 23:02
-
1ok, I noticed that I was missing the .view. part of the import. Now, the itemView reference is available, and it seems to come from RecyclerView.ViewHolder class in v7 support package. Tks – Saulo Aguiar Dec 17 '16 at 23:52
-
1`itemView` is a property of the base type (`RecyclerView.ViewHolder`) – Marcin Koziński Dec 21 '16 at 17:39
-
4There's no cache for view extensions, so references to views should be cached, like in ordinary viewHolder. – Miha_x64 Jun 10 '17 at 07:41
-
3@Mike since Kotlin 1.1.4 all views are going to be cached. Even in ViewHolders. The Article you posted does mention this as well. – Stefan Medack Oct 05 '17 at 12:41
-
2@StefanMedack I am the author of the article :) Although I have to point that it is only part of the experimental features and needs to be manually enabled. I haven't tried it yet. – Miguel Beltran Oct 05 '17 at 12:56
-
1
-
Here are some details about caching in 1.1.4 - https://stackoverflow.com/a/46646302/1000551 – Vadim Kotov Sep 30 '20 at 15:11
-
As @Vadim Kotov has mentioned, LayoutContainer has to be implemented for views to be cached and they have to be referenced directly -> `date.text = forecast.date.toDateString()` otherwise findViewById is called each time. – Roman Droppa Jan 21 '21 at 10:25
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!"
}
}

- 8,084
- 8
- 48
- 62

- 9,467
- 2
- 48
- 42
-
3Adding to this information: As per Kotlin 1.1.4 the feature is experimental and needs to be enabled on the build.gradle file – Miguel Beltran Oct 05 '17 at 12:58
-
2Is this experimental any longer? I want to use this in production code – Carson Holzheimer Mar 27 '18 at 14:52
-
-
seems it doesn't even work with `1.3.21`. I think they aren't going to implement it – user924 Feb 26 '19 at 12:26
-
but we can use `containerView.itemTitle.text = "Hello Kotlin!"` and I think it's enough – user924 Feb 26 '19 at 12:29
-
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.

- 1,219
- 1
- 12
- 29
-
1answer was already given https://stackoverflow.com/a/33428208/7767664 why did you repeat it? – user924 Feb 26 '19 at 12:35
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

- 8,084
- 8
- 48
- 62

- 755
- 1
- 14
- 24
-
answer was already given https://stackoverflow.com/a/33428208/7767664 why did you repeat it? – user924 Feb 26 '19 at 12:34
-
@ user924. if answer is already in another thread, please moderate and mark current thread as duplicate and add reference to other thread – hyena Feb 27 '19 at 03:30
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)
}

- 33,936
- 20
- 234
- 300
-
Is there any official confirmation about this? I believe using `.view.*` import defeats the purpose, the fallback will be to `findViewById<>` , each time -- the very pattern a `ViewHolder` dissuades from. – Skynet Aug 27 '20 at 17:46
-
Explained at: https://proandroiddev.com/kotlin-android-extensions-using-view-binding-the-right-way-707cd0c9e648 – Skynet Aug 27 '20 at 17:49
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.

- 31,429
- 6
- 80
- 66
-
1I have seen it yet. I have do it for my activity, as I described above. But how I can use it inside BaseAdapter derivatives? – busylee Oct 23 '15 at 15:12
-
1Well, basically you can invoke `findViewById()` method on a `View`, like `holder.findViewById(R.id.name)`. With Kotlin Android Extensions you can write just `holder.name`. Suppose this code is written inside a `getView()` function: `val base = inflater.inflate(R.layout.list_item, parent, false)` `base.name.text = "John Smith"` – yanex Oct 23 '15 at 23:09
-
But what if I have to use several view holders with various layouts? How can I realize it with synthetic? Because we have to use specific "synthetic link" for each layout and I have several layouts with similar ids. – Natan Rubinstein Aug 29 '17 at 21:48
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.

- 12,852
- 7
- 62
- 94