No se puede "findViewById" en Kotlin. Obteniendo el error "Falló la inferencia de tipo"

Recibo el siguiente error cuando trato de encontrar un RecycleView por id.

Error: – Falló la inferencia de tipo: No hay información suficiente para inferir el parámetro T

Error

Código:

 class FirstRecycleViewExample : AppCompatActivity() { val data = arrayListOf<String>() 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 } } 

Pruebe algo como:

 val recyclerView = findViewById<RecyclerView>(R.id.recycler_view) 

También puedes usar Kotlin Android Extensions . Verifique el documento aquí .
Con él, puedes llamar a recycler_view directamente en tu código.

Extensiones de Kotlin para Android:

  • En tu aplicación gradle.build agrega el apply plugin: 'kotlin-android-extensions'
  • En su class, agregue importar para import kotlinx.android.synthetic.main.<layout>.* Donde <layout> es el nombre de file de su layout.
  • Eso es todo, puedes llamar a recycler_view directamente en tu código.

¿Como funciona? La primera vez que llama a recycler_view , se realiza y almacena en caching una llamada a findViewById .

Estás en el nivel 26 de API, donde el tipo de retorno de findViewById ahora es una T genérica en lugar de View y, por lo tanto, se puede inferir. Puede ver el logging de cambios relevante aquí .

Entonces deberías poder hacer esto:

 val recycler_view = findViewById<RecyclerView>(R.id.recycler_view) 

O esto:

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

Por lo general, Kotlin puede inferir su tipo utilizando la información provista entre corchetes.

En este caso, no puede, por lo que tendría que especificarlo explícitamente así

 findViewById<RecyclerView>(R.id.recycler_view) 

Aunque no estoy seguro del tipo, pero así es como debes especificarlo

Me gustaría agregar que, usando Anko , puedes simplificar aún más tu código así:

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

En Kotlin podemos get el id de la vista sin el uso de la syntax findViewById .

Por ejemplo, estamos usando el siguiente layout desde el cual obtendremos el id de la vista y realizaremos la operación

Diseño

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/welcomeMessage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Hello World!"/> </FrameLayout> 

Podemos encontrar la identificación de la vista usando el siguiente código

 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 } 

¿CÓMO?

Para poder usarlo, necesita una import especial (la que escribo a continuación), pero el IDE puede importarla automáticamente. No podría ser más fácil!

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

Necesitamos importar esta propiedad para get el id de la vista sin el uso de la syntax de findviewbyid .

Para get más información sobre este tema, consulte este enlace: – Haga clic aquí

Prueba esto:

Aquí se bind uso de la function genérica para vincular la vista. su function general puede usarse para cualquier vista.

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

Puede ignorar dar identificadores a las variables en kotlin. Solo necesitas usar un plugin

Pega esto en tu gradle

  apply plugin: 'kotlin-android-extensions' 

y luego no necesitas asignar identificadores a var, solo puedes hacerlo como

  recycler_view.setAdapter(youradapter); 

Código: Otra forma de hacerlo.

 class KotlinActivity : AppCompatActivity() { var recycler_view: RecyclerView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_kotlin) recycler_view = findViewById<RecyclerView>(R.id.recycler_view) } } 

Agregue esta línea para su código como Lo que sea que esté usando el controller.

 val tvHello = findViewById<TextView>(R.id.tvHello)