extensions android android-layout kotlin type-inference

android - extensions - No se puede "findViewById" en Kotlin. Obteniendo error "Inferencia de tipo fallida"



kotlin android extensions (9)

Recibo el siguiente error cuando intento encontrar un RecycleView por id.

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

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 } }


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 esté utilizando el controlador.

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


En Kotlin podemos obtener la identificación de la vista sin el uso de la sintaxis findViewById .

Por ejemplo, estamos utilizando el siguiente diseño a partir del cual obtendremos la identificación 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 importación 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 obtener la identificación de la vista sin el uso de la sintaxis findviewbyid .

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


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 registro de cambios relevante here .

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)


Intenta algo como:

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

También puedes usar Kotlin Android Extensions para eso. Consulta el documento here .
Con él, puede llamar a recycler_view directamente en su código.

Extensiones de Android Kotlin:

  • En su aplicación, gradle.build agrega el apply plugin: ''kotlin-android-extensions''
  • En su clase, agregue import for import kotlinx.android.synthetic.main.<layout>.* Donde <layout> es el nombre de archivo de su diseño.
  • Eso es todo, puede llamar a recycler_view directamente en su código.

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


Ni siquiera tiene que crear un objeto para hacer cosas con una vista. Puedes usar la identificación. Por ejemplo, Kotlin.

recycle_view.adapter = adapter

es lo mismo que Java

RecycleView recycle_view = (RecycleView) findViewById(recycle_view); recycle_view.setAdapter(adapter);


Por lo general, Kotlin puede inferir su tipo utilizando la información proporcionada entre paréntesis.

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

findViewById<RecyclerView>(R.id.recycler_view)

Sin embargo, no estoy muy seguro sobre el tipo, pero así es como debe especificarlo

Me gustaría agregar que, usando Anko , puede simplificar aún más su código de esta manera:

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


Prueba esto:

Aquí bind utiliza la función genérica de vinculación para vincular la vista. su función general se puede usar 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 complemento

Pega esto en tu gradle

apply plugin: ''kotlin-android-extensions''

y luego no necesita asignar identificadores a var, simplemente puede hacerlo como

recycler_view.setAdapter(youradapter);