"ViewViewById" in Kotlin nicht möglich. Fehler "Typinferenz fehlgeschlagen"


80

Ich erhalte die folgende Fehlermeldung, wenn ich versuche, eine RecycleViewID zu finden .

Fehler: - Typinferenz fehlgeschlagen: Nicht genügend Informationen, um auf Parameter T zu schließen

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

Antworten:


100

Versuchen Sie etwas wie:

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

Sie können Kotlin Android Extensionsauch dafür verwenden. Überprüfen Sie das Dokument hier .
Damit können Sie recycler_viewdirekt Ihren Code aufrufen .

Kotlin Android-Erweiterungen:

  • In Ihrer App gradle.buildhinzufügenapply plugin: 'kotlin-android-extensions'
  • In Ihrer Klasse hinzufügen Import für import kotlinx.android.synthetic.main.<layout>.*wo <layout>ist der Dateiname des Layouts.
  • Das war's, Sie können recycler_viewdirekt in Ihrem Code aufrufen .

Wie funktioniert es? Wenn Sie zum ersten Mal anrufen recycler_view, wird ein Anruf bei findViewByIdgetätigt und zwischengespeichert .


In der neuesten Version wird eine Warnung angezeigt, dass der Typ aus <> entfernt werden soll. Da Android Studio mich zwingt, nur den Diamantoperator zu verwenden, <>wenn ich ihn verwende, gibt es einen Fehler.
Asif Mushtaq

46

Sie sind auf API - Ebene 26, wo der Rückgabetyp findViewByIdjetzt ist ein generisches Tstatt Viewund deshalb geschlossen werden kann. Das entsprechende Änderungsprotokoll sehen Sie hier .

Sie sollten also in der Lage sein, dies zu tun:

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

Oder dieses:

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

7

In können Kotlinwir die ID der Ansicht ohne Verwendung der findViewByIdSyntax erhalten.

Zum Beispiel verwenden wir das folgende Layout, aus dem wir die ID der Ansicht abrufen und den Vorgang ausführen

Layout

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

Wir können die ID der Ansicht mithilfe des folgenden Codes ermitteln

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
}

WIE?

Um es verwenden zu können, benötigen Sie einen speziellen Import (den, den ich unten schreibe), aber die IDE kann ihn automatisch importieren. Einfacher geht es nicht!

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

Wir müssen diese Eigenschaft importieren, um die ID der Ansicht ohne Verwendung der findviewbyidSyntax zu erhalten.

Weitere Informationen zu diesem Thema finden Sie unter folgendem Link: - Klicken Sie hier


1
Geniale Lösung! Hat mir viel geholfen!
Gundrabur

7

Normalerweise kann Kotlin Ihren Typ anhand der Informationen in den Klammern ableiten.

In diesem Fall ist dies nicht möglich, sodass Sie es explizit so angeben müssen

findViewById<RecyclerView>(R.id.recycler_view)

Ich bin mir zwar nicht sicher über den Typ, aber so sollten Sie ihn angeben

Ich möchte hinzufügen, dass Sie mit Anko Ihren Code wie folgt weiter vereinfachen können:

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

4

Fügen Sie diese Zeile für Ihren Code als Was auch immer Sie verwenden Controller hinzu.

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

1

Sie können das Geben von IDs für Variablen in Kotlin ignorieren. Sie müssen nur ein Plugin verwenden

Fügen Sie dies in Ihren Gradle ein

 apply plugin: 'kotlin-android-extensions'

und dann müssen Sie var keine IDs zuweisen, Sie können es einfach so machen

 recycler_view.setAdapter(youradapter);

Bitte geben Sie einen Grund für die Ablehnung an.
Anmol317

1

Versuche dies:

Hier wird die bindgenerische Funktion zum Binden der Ansicht verwendet. Seine allgemeine Funktion kann für jede Ansicht verwendet werden.

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
Bitte fügen Sie Ihrem Code eine Erklärung hinzu. Antworten nur mit Code werden nicht empfohlen.
Willi Mentzel

1
hinzugefügt. @ WilliMentzel
Mehul Kabaria

0

Sie müssen nicht einmal ein Objekt erstellen, um Dinge mit einer Ansicht zu tun. Sie können einfach die ID verwenden. Zum Beispiel Kotlin

recycle_view.adapter = adapter

ist das gleiche wie Java

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

0

War nicht in der Lage, auf die UI-Komponenten zuzugreifen.

plugins {
    ...
    id 'kotlin-android-extensions'
}

Obwohl Android Studio nach dem Hinzufügen dieser Zeile die Importe für Kotlin-Kunststoffe immer noch nicht automatisch auflösen konnte, müssen Sie möglicherweise den Cache ungültig machen und neu starten.

Wenn dies immer noch nicht funktioniert, importieren Sie es je nach Ansicht manuell

  • Aktivitäts- / Fragmentansicht: Importieren Sie kotlinx.android.synthetic.main. <Ihre_Aktivitätsansicht>. *
  • Normale Ansichten: Importieren Sie kotlinx.android.synthetic.main. <Ihre_Layout_Ansicht> .Ansicht. *

Update - 2

Wenn Sie diese Info-Warnung erhalten -

Warnung: Das Gradle-Plugin "Kotlin-Android-Erweiterungen" ist veraltet.

Plugin 'Kotlin-Android-Erweiterungen' wird veraltet sein. Fügen Sie also unten in Ihrem App-Gradle hinzu

android {
    ...
    buildFeatures {
        viewBinding true
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.