Nicht aufgelöste Referenz für die synthetische Ansicht, wenn sich das Layout im Bibliotheksmodul befindet

Lesezeit: 6 Minuten

Benutzer-Avatar
Martynas Jurkus

mit Kotlin 1.20.20 (nicht dass es wichtig wäre, ältere Versionen verhalten sich gleich)

Wenn sich das Layout in einem separaten Bibliotheksmodul befindet, hat Android Studio keine Probleme, die Ansicht zu finden und zu referenzieren

import kotlinx.android.synthetic.main.view_user_input.*

Aber wenn ich versuche, die App zu kompilieren, schlägt sie fehl Unresolved reference: view_user_input an :app:compileDebugKotlin.

Alles funktioniert gut, wenn auf die Ansicht im Bibliotheksmodul verwiesen wird.

Übersehe ich hier etwas?

Projektstruktur hinzufügen. Alle Module verwenden Kotlin und Kotlin-Erweiterungen.

build.gradle
app/
  build.gradle //main application
library-module-a/
  build.gradle //library application
library-module-b/
  build.gradle //library application

Hier ist eine Beispiel-App https://github.com/mjurkus/KotlinxTest

Registrierte Ausgabe dafür in KT-Tracker

  • wo definierst du kotlin buildScript? im Projekt oder Modul ?

    – Hemant Parmar

    22. Januar 2018 um 9:58 Uhr

  • Im Projekt. Wenn Sie fragen, wo ` classpath “org.jetbrains.kotlin:kotlin-android-extensions:$KOTLIN_VERSION”` definiert ist.

    – Martynas Jurkus

    22. Januar 2018 um 10:04 Uhr

  • gerade aus dem Projekt entfernt und im Modul hinzugefügt.

    – Hemant Parmar

    22. Januar 2018 um 10:04 Uhr

  • Wieso den? Könnten Sie näher darauf eingehen?

    – Martynas Jurkus

    22. Januar 2018 um 10:09 Uhr

  • Kotlin Synthetics sind veraltet, also ziehen Sie in Betracht, zu wechseln ViewBinding das von Android Gradle Plugin 3.6.0 (derzeit RC03) verfügbar ist. Dies ist die neue von Google empfohlene Methode für den Zugriff auf Ansichten, die in Layout-XML deklariert sind.

    – Markieren

    1. September 2020 um 4:00 Uhr


Benutzer-Avatar
pablisko

Aktualisieren:

Synthetische Ansichtsreferenzen sind veraltet und werden in Zukunft nicht mehr unterstützt.

Die aktuelle empfohlene Lösung ist zu verwenden ViewBinding (oder auf Jetpack Compose warten)

Ursprüngliche Antwort:

Eine Möglichkeit, dies zu lösen, besteht darin, eine „Alias“-Eigenschaft zu erstellen, die von anderen Modulen verwendet werden kann:

// SyntheticExports.kt
package com.example.synthetic.exported

import kotlinx.android.synthetic.main.layout_in_library.*

inline val Activity.exported_text_view get() = text_view

Dann auf dem anderen Modul:

// MainActivity.kt
import com.example.synthetic.exported.exported_text_view

exported_text_view.text = "example"

Das funktioniert für uns. Müssen verschiedene Erweiterungen für erstellen view, fragmentusw. Es ist ein bisschen mühsam, sie manuell auszuführen, aber dies ist die einfachste Problemumgehung, die wir gefunden haben.

Extra: Dies ist auch eine anständige Methode, um synthetische Erweiterungen auch als Teil einer öffentlichen Bibliothek zu exportieren, nicht nur in einem internen Modul.

Benutzer-Avatar
Meda

Keine der obigen Antworten hat mir wirklich geholfen. Fügen Sie diese beiden Plugins oben in Ihrer build.gradle-Datei auf App-Ebene hinzu:

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

Dies sollte das Problem lösen.

ODER

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

  • @Medha Es würde helfen, wenn Sie genauer sein könnten. Wenn ich mich nicht irre, sollten Sie die folgende Zeile in der build.gradle-Datei für das Modul (im Gegensatz zum Projekt) hinzufügen: id ‘kotlin-android-extensions’ in den geschweiften Klammern für das Plugin.

    – nayriz

    20. Dezember 2020 um 15:01 Uhr

Benutzer-Avatar
Anh Duy

Ich habe auch dieses Problem und meine Lösung ist:

  • Verwenden Sie keinen Import kotlinx.android.synthetic.main....*

  • Verwenden findViewById()

Zum Beispiel wechselte ich von

textview_id.text = "abc"

zu

findViewById(R.id.textview_id).text = "abc"

  • Mit Abstand die einfachste Lösung!

    – xeruf

    19. Januar 2019 um 16:30 Uhr

  • Nun …. der Sinn von all dem ist nicht, findViewById zu verwenden, oder?

    – Egonal

    19. Juni 2020 um 8:02 Uhr

Die Lösung ist viel einfacher als gedacht, Kotlin Synthetic Sugars sind Teil der Kotlin Android Extensions und Sie müssen das Plugin nur manuell anwenden (Android Studio wendet dies automatisch nur auf Anwendungsmodule an):

Fügen Sie dem Gradle-Build Ihrer Bibliothek / Ihres Funktionsmoduls Folgendes hinzu:

apply plugin: 'kotlin-android-extensions'

Genießen Sie jetzt synthetischen Kotlin-Zucker in Ihrem Kotlin-Code! 😉

Benutzer-Avatar
Ivan Morgillo

du könntest versuchen zu wechseln 1.2.30-eap-16 und hinzufügen

androidExtensions {
    experimental = true
}

zu deinem build.gradle.

  • Ich habe das Problem im Kotlin Issue Tracker für dieses Problem registriert.

    – Martynas Jurkus

    15. Februar 2018 um 13:35 Uhr

  • Die Lösung hat bei mir nicht funktioniert. Ich habe versucht, das experimentelle Flag im Bibliotheksmodul mit dem Layout hinzuzufügen. Es hat nicht funktioniert. Dann habe ich dem Modul auch das Flag hinzugefügt, das vom ersten abhängt, das das Layout enthält. Es funktioniert auch nicht. Anscheinend hat JetBrains das Problem noch nicht behoben: youtrack.jetbrains.com/issue/KT-22430

    – Cesaren

    5. November 2018 um 13:28 Uhr

  • das androidExtensions { experimental = true } hat bei mir funktioniert

    – raquezha

    16. Mai 2019 um 4:01 Uhr

Benutzer-Avatar
SafaOrhan

Wie im obigen Kommentar von @cesards erwähnt, ist dies der Fall ein Dauerthema mit den Kotlin Android Extensions. Und es ist bis heute nicht gelöst.


Gut: Verwenden Sie benutzerdefinierte Ansichten

Mein primärer Vorschlag ist, die Ansicht und das relevante Verhalten als benutzerdefinierte Ansicht zu kapseln und sie nicht über einzuschließen <include> Tag, verwenden Sie es direkt in Ihrem Layout als <com.example.app.YourCustomView>.

Dies funktioniert unabhängig davon, ob sich Ihre Ansichtsklasse in einem anderen Modul befindet oder nicht.


Schlecht und hässlich: Problemumgehung für ID-Kollision

Ich habe jedoch eine hackige Problemumgehung gefunden, wenn Sie nur zugreifen möchten eine Referenz aus der enthaltenen Ansicht.

Befolgen Sie diese Schritte, um synthetische Kotlin-Importe für die Layouts zu verwenden, die aus anderen Modulen enthalten sind:

  1. Geben Sie der Ansicht, auf die Sie in der enthaltenen XML-Datei verweisen möchten, eine ID.
  2. Weisen Sie dem include-Tag in der inkludierenden XML-Datei dieselbe ID zu.
  3. Importieren Sie nun synthetisch die Ansicht (ID) aus dem inkludierenden Layout (nicht aus dem inkludierten)

Ich bin mir nicht sicher, wie und warum das funktioniert, aber es ist eine sehr zerbrechliche und schmutzige Art, Layouts wiederzuverwenden.

Beispiel:

Ihr inklusives Layout (fragment_example.xml)

<include
    android:id="@+id/exampleView"
    layout="@layout/example_layout" />

Ihr eingebundenes Layout (example_layout.xml)

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/exampleView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</merge>

Ihre Fragmentklasse (ExampleFragment.kt)

import kotlinx.android.synthetic.main.fragment_example.exampleView

// Do not import the exampleView through example_layout.exampleView

class ExampleFragment : Fragment() {
    // Do something with imported exampleView
}

  • Ich habe das Problem im Kotlin Issue Tracker für dieses Problem registriert.

    – Martynas Jurkus

    15. Februar 2018 um 13:35 Uhr

  • Die Lösung hat bei mir nicht funktioniert. Ich habe versucht, das experimentelle Flag im Bibliotheksmodul mit dem Layout hinzuzufügen. Es hat nicht funktioniert. Dann habe ich dem Modul auch das Flag hinzugefügt, das vom ersten abhängt, das das Layout enthält. Es funktioniert auch nicht. Anscheinend hat JetBrains das Problem noch nicht behoben: youtrack.jetbrains.com/issue/KT-22430

    – Cesaren

    5. November 2018 um 13:28 Uhr

  • das androidExtensions { experimental = true } hat bei mir funktioniert

    – raquezha

    16. Mai 2019 um 4:01 Uhr

Benutzer-Avatar
Braian Coronel

Voraussetzungen

Importieren Sie nicht die folgende Bibliothek import kotlinx.android.synthetic.main.my_view.view.*

app/MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val view: View = MyView(this)
        view.findViewById<TextView>(R.id.textViewPocLib).text = "I can edit the library components"
        setContentView(view)
}

meine_bibliothek/MyView.kt

class MyView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    LinearLayout(context, attrs, defStyleAttr) {

    init {
        LayoutInflater.from(context)
            .inflate(R.layout.my_view, this, true)
    }
}

GL

Quellen:

1078100cookie-checkNicht aufgelöste Referenz für die synthetische Ansicht, wenn sich das Layout im Bibliotheksmodul befindet

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy