Kotlin: Not able to “findViewById” in Kotlin. Getting error “Type inference failed”

Kotlin Programming

Question or issue of Kotlin Programming:

I am getting the following error when I try to find a RecycleView by id.

Code:

class FirstRecycleViewExample : AppCompatActivity() {
val data = arrayListOf()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.first_recycleview)
val recycler_view = findViewById(R.id.recycler_view) as RecyclerView ///IN THIS LINE I AM GETTING THE ERROR
data.add("First Data")
data.add("Second Data")
data.add("Third Data")
data.add("Forth Data")
data.add("Fifth Data")
//creating our adapter
val adapter = CustomRecycleAdapter(data)
//now adding the adapter to recyclerview
recycler_view.adapter = adapter
}
}
class FirstRecycleViewExample : AppCompatActivity() { val data = arrayListOf() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.first_recycleview) val recycler_view = findViewById(R.id.recycler_view) as RecyclerView ///IN THIS LINE I AM GETTING THE ERROR data.add("First Data") data.add("Second Data") data.add("Third Data") data.add("Forth Data") data.add("Fifth Data") //creating our adapter val adapter = CustomRecycleAdapter(data) //now adding the adapter to recyclerview recycler_view.adapter = adapter } }
class FirstRecycleViewExample : AppCompatActivity() {
    val data = arrayListOf()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.first_recycleview)

        val recycler_view =  findViewById(R.id.recycler_view) as RecyclerView ///IN THIS LINE I AM GETTING THE ERROR

        data.add("First Data")
        data.add("Second Data")
        data.add("Third Data")
        data.add("Forth Data")
        data.add("Fifth Data")

        //creating our adapter
        val adapter = CustomRecycleAdapter(data)

        //now adding the adapter to recyclerview
        recycler_view.adapter = adapter
    }
}

How to solve this issue?

Solution no. 1:

Try something like:

val recyclerView = findViewById(R.id.recycler_view)
val recyclerView = findViewById(R.id.recycler_view)
val recyclerView = findViewById(R.id.recycler_view)

You can use Kotlin Android Extensions too for that. Check the doc here.
With it, you can call recycler_view directly in your code.

Kotlin Android Extensions:

  • In your app gradle.build add apply plugin: 'kotlin-android-extensions'
  • In your class add import for import kotlinx.android.synthetic.main.<layout>.* where <layout> is the filename of your layout.
  • That’s it, you can call recycler_view directly in your code.

How does it work? The first time that you call recycler_view, a call to findViewById is done and cached.

Solution no. 2:

You’re on API level 26, where the return type of findViewById is now a generic T instead of View and can therefore be inferred. You can see the relevant changelog here.

So you should be able to do this:

val recycler_view = findViewById(R.id.recycler_view)
val recycler_view = findViewById(R.id.recycler_view)
val recycler_view = findViewById(R.id.recycler_view)

Or this:

val recycler_view: RecyclerView = findViewById(R.id.recycler_view)
val recycler_view: RecyclerView = findViewById(R.id.recycler_view)
val recycler_view: RecyclerView = findViewById(R.id.recycler_view)

Solution no. 3:

In Kotlin we can get the id of the view without the use of the findViewById syntax.

For example we are using the following the layout from that we will get the id of the view and perform operation


Layout

<em> </em>
<em> </em>
 

We are able to find the id of the view by using the following code

<em>override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) welcomeMessage.text = "Hello Kotlin!" ////WE ARE GETTING THE IDS WITHOUT USING THE FINDVIEWBYID syntax } </em>
<em>override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) welcomeMessage.text = "Hello Kotlin!" ////WE ARE GETTING THE IDS WITHOUT USING THE FINDVIEWBYID syntax } </em>
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) welcomeMessage.text = "Hello Kotlin!" ////WE ARE GETTING THE IDS WITHOUT USING THE FINDVIEWBYID syntax } 


HOW?

To be able to use it, you need an special import (the one I write below), but the IDE is able to auto-import it. Couldn’t be easier!

<em>import kotlinx.android.synthetic.main.YOUR_LAYOUT_NAME.*/// HERE "YOUR_LAYOUT_NAME" IS YOUR LAYOUT NAME WHICH U HAVE INFLATED IN onCreate()/onCreateView() </em>
<em>import kotlinx.android.synthetic.main.YOUR_LAYOUT_NAME.*/// HERE "YOUR_LAYOUT_NAME" IS YOUR LAYOUT NAME WHICH U HAVE INFLATED IN onCreate()/onCreateView() </em>
import kotlinx.android.synthetic.main.YOUR_LAYOUT_NAME.*/// HERE "YOUR_LAYOUT_NAME" IS YOUR LAYOUT NAME WHICH U HAVE INFLATED IN onCreate()/onCreateView() 

We need to import this property to get the id of the view without the use of the findviewbyid syntax.

For more information on this topic than please refer this link :- Click here

Solution no. 4:

Usually Kotlin can infer your type using the info provided in the brackets.

In this case, it can’t so you would have to specify it explicitly like this

<em>findViewById(R.id.recycler_view) </em>
<em>findViewById(R.id.recycler_view) </em>
findViewById(R.id.recycler_view) 

Not really sure about the type though but that is how you should specify it

I’d like to add that, using Anko, you can further simplify your code like this:

<em>val recycler_view : RecyclerView = find(R.id.recycler_view) </em>
<em>val recycler_view : RecyclerView = find(R.id.recycler_view) </em>
val recycler_view : RecyclerView = find(R.id.recycler_view) 

Solution no. 5:

Add this line for your code as Whatever you are using controller.

<em>val tvHello = findViewById(R.id.tvHello) </em>
<em>val tvHello = findViewById(R.id.tvHello) </em>
val tvHello = findViewById(R.id.tvHello) 

Solution no. 6:

You can ignore giving ids to variables in kotlin. You just need to use a plugin

Paste this in your gradle

<em> apply plugin: 'kotlin-android-extensions' </em>
<em> apply plugin: 'kotlin-android-extensions' </em>
 apply plugin: 'kotlin-android-extensions' 

and then you don’t need to assign ids to var, you can just do it like

<em> recycler_view.setAdapter(youradapter); </em>
<em> recycler_view.setAdapter(youradapter); </em>
 recycler_view.setAdapter(youradapter); 

Solution no. 7:

Try this:

Here bind generic function use to bind view. its general function it’s can use for any view.

<em>class MyActivity : AppCompatActivity() { private lateinit var recycler_view : RecyclerView override fun onCreate(savedInstanceState: Bundle?) { ... recycler_view = bind(R.id.recycler_view) } } fun Activity.bind(@IdRes res : Int) : T { @Suppress("UNCHECKED_CAST") return findViewById(res) as T } </em>
<em>class MyActivity : AppCompatActivity() { private lateinit var recycler_view : RecyclerView override fun onCreate(savedInstanceState: Bundle?) { ... recycler_view = bind(R.id.recycler_view) } } fun Activity.bind(@IdRes res : Int) : T { @Suppress("UNCHECKED_CAST") return findViewById(res) as T } </em>
class MyActivity : AppCompatActivity() { private lateinit var recycler_view : RecyclerView override fun onCreate(savedInstanceState: Bundle?) { ... recycler_view = bind(R.id.recycler_view) } } fun Activity.bind(@IdRes res : Int) : T { @Suppress("UNCHECKED_CAST") return findViewById(res) as T } 

Solution no. 8:

You don’t even have to create an object to do things with a view.
You can just use the id. For example,
Kotlin

<em>recycle_view.adapter = adapter </em>
<em>recycle_view.adapter = adapter </em>
recycle_view.adapter = adapter 

is same as,
Java

<em>RecycleView recycle_view = (RecycleView) findViewById(recycle_view); recycle_view.setAdapter(adapter); </em>
<em>RecycleView recycle_view = (RecycleView) findViewById(recycle_view); recycle_view.setAdapter(adapter); </em>
RecycleView recycle_view = (RecycleView) findViewById(recycle_view); recycle_view.setAdapter(adapter); 

Solution no. 9:

Was unable to access the ui components like OP faced looks like below was needed inside app gradle:

<em>plugins { ... id 'kotlin-android-extensions' } </em>
<em>plugins { ... id 'kotlin-android-extensions' } </em>
plugins { ... id 'kotlin-android-extensions' } 

Even though after adding this line android studio was still not able to auto resolve the imports for kotlin synthetics so you may need to invalidate cache and restart.

If still not working then import manually depending on views

  • activity /fragment view: import
    kotlinx.android.synthetic.main.<your_activity_view>.*
  • normal views :
    import kotlinx.android.synthetic.main.<your_layout_view>.view.*

Update – 2

If you are getting this info warning –


Warning: The ‘kotlin-android-extensions’ Gradle plugin is deprecated.

plugin ‘kotlin-android-extensions’ is going to be deprecated.
So add below in your app gradle

<em>android { ... buildFeatures { viewBinding true } } </em>
<em>android { ... buildFeatures { viewBinding true } } </em>
android { ... buildFeatures { viewBinding true } } 

Hope this helps!