web-dev-qa-db-fra.com

Impossible de "findViewById" dans Kotlin. Obtention de l'erreur "Echec de l'inférence de type"

Je reçois le message d'erreur suivant lorsque j'essaie de trouver une RecycleView par identifiant.

Erreur:- Echec de l'inférence de type: informations insuffisantes pour déduire le paramètre T

 Error

Code:

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
    }
}
60
Ravindra Kushwaha

Essayez quelque chose comme:

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

Vous pouvez aussi utiliser Kotlin Android Extensions pour cela. Vérifiez la doc ici .
Avec cela, vous pouvez appeler recycler_view directement dans votre code.

Extensions Android Kotlin:

  • Dans votre application gradle.build ajouter apply plugin: 'kotlin-Android-extensions'
  • Dans votre classe, ajoutez import pour import kotlinx.Android.synthetic.main.<layout>.*, où <layout> est le nom du fichier de votre mise en page.
  • Ça y est, vous pouvez appeler recycler_view directement dans votre code.

Comment ça marche? La première fois que vous appelez recycler_view, un appel à findViewById est effectué et mis en cache.

83
Kevin Robatel

Vous êtes au niveau 26 de l'API, où le type de retour findViewById est maintenant un générique T au lieu de View et peut donc être déduit. Vous pouvez voir le journal des modifications correspondant ici .

Donc, vous devriez pouvoir faire ceci:

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

Ou ca:

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

Habituellement, Kotlin peut déduire votre type en utilisant les informations fournies entre parenthèses.

Dans ce cas, il ne peut pas vous obliger à le spécifier explicitement comme ceci 

findViewById<RecyclerView>(R.id.recycler_view)

Pas vraiment sûr du type, mais c'est comme ça que vous devriez le spécifier 

Je voudrais ajouter que, en utilisant Anko , vous pouvez simplifier votre code comme ceci:

val recycler_view : RecyclerView =  find(R.id.recycler_view)
6
Alf Moh

Dans Kotlin, nous pouvons obtenir l'id de la vue sans utiliser la syntaxe findViewById.

Par exemple, nous utilisons la disposition suivante pour obtenir l'id de la vue et effectuer l'opération. 

Disposition

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

Nous sommes en mesure de trouver l'id de la vue en utilisant le code suivant

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
}

COMMENT?

Pour pouvoir l'utiliser, vous avez besoin d'une importation spéciale (celle que j'écris ci-dessous), mais le IDE peut l'importer automatiquement. Cela ne pourrait pas être plus facile!

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

Nous devons importer cette propriété pour obtenir l'identifiant de la vue sans utiliser la syntaxe findviewbyid.

Pour plus d'informations sur ce sujet, veuillez vous référer à ce lien: - Cliquez ici

5
Ravindra Kushwaha

Ajoutez cette ligne pour votre code en tant que tout ce que vous utilisez le contrôleur.

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

Essaye ça:

Ici, bind fonction générique utilise pour lier la vue. sa fonction générale, il peut être utilisé pour n'importe quelle vue.

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
}
1
Mehul Kabaria

Vous pouvez ignorer l'attribution d'identifiants aux variables dans Kotlin. Vous avez juste besoin d'utiliser un plugin

Collez ceci dans votre grade

 apply plugin: 'kotlin-Android-extensions'

et alors vous n'avez pas besoin d'attribuer les identifiants à var, vous pouvez simplement le faire comme

 recycler_view.setAdapter(youradapter);
0
Anmol

Vous n'avez même pas besoin de créer un objet pour faire des choses avec une vue .. Vous pouvez simplement utiliser l'identifiant. Par exemple, Kotlin

recycle_view.adapter = adapter

est identique à, Java

RecycleView recycle_view = (RecycleView) findViewById(recycle_view);
recycle_view.setAdapter(adapter);
0
Ajay Sivan

Code: Une autre façon de le faire.

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)


        }
    }
0
Siddhant Patil