Klasa powiązania danych nie została wygenerowana

101

Używam powiązania danych w moim projekcie, gdy używam <layout>iw <data>mojej klasie powiązań XML nie jest generowana.

Na przykład mam activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>    </data>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </RelativeLayout>
</layout>

Teraz, jeśli piszę ActivityMainBindingw mojej aktywności / fragmencie, pokazuje błąd, że klasa nie jest dostępna. Ale po <variable>dołączeniu do mojego pliku xml jest w stanie wygenerować ActivityMainBindingklasę.

Android Studio: 2.1.3
Classpath: com.android.tools.build:gradle:2.1.3
minSdkVersion 16
targetSdkVersion 24
buildToolsVersion 24.0.0

Ravi
źródło
2
jest dataBinding.enabledw twoim build.gradle?
pskink
2
Myślę, że to znany błąd. Możesz spróbować zbudować swój projekt, zanim spróbujesz uzyskać dostęp ActivityMainBinding, lub musi to zrobić z tym błędem.
yennsarah
@pskink tak jest, dlatego generuje klasę wiązania po dodaniu <variable>w xml
Ravi
@Amylinn po zbudowaniu mojego projektu generuje, ale moje pytanie brzmi, kiedy piszę <variable>, generuje wiążącą klasę bez budowania projektu.
Ravi,
1
Nie rozumiem prawdziwego pytania? jeśli dodanie <variable> może rozwiązać problem, dlaczego tego nie zrobisz? nie rozumiem punktu wiązania bez ViewModel (<variable>)
ktutnik

Odpowiedzi:

225

Nie otrzymałem zadowalających odpowiedzi. Oto wskazówki, które są podsumowaniem mojej wiedzy na temat wiązania danych.

Wskazówki dotyczące rozwiązywania problemów z wiązaniem danych

Aktualizacja

Aby uzyskać dokładniejsze błędy i sugestie , zdecydowanie zalecamy aktualizację wersji wtyczki Android Studio i Gradle do najnowszej. Ponieważ po wersji AS 3.2 nie mam wielu problemów.

Zobacz najnowsze Android Studio i najnowszą wtyczkę Gradle .

Oryginalne rozwiązanie

Po przeczytaniu tej odpowiedzi nie utkniesz w problemach z automatycznym generowaniem powiązań danych zarówno dla klas, jak i zmiennych danych .

Sprawdź te punkty jeden po drugim. Każdy z nich może sprawić, że Twoja praca będzie wykonana. Ostatni punkt jest naprawdę ważny, więc nie przegap ich.

1. Sprawdź, czy włączono wiązanie danych

Powinieneś mieć włączone powiązanie danych w programie build.gradle. Jeśli nie, dodaj to i Synchronizuj .

android {
...
   dataBinding {
        enabled = true
    }
...
}

2. Układ sprawdzenia jest konwertowany na układ oprawy

Teraz, jeśli chcesz, aby klasa powiązania danych została wygenerowana, powinieneś opakować xml layoutwiązaniem danych ( <layouttag). Coś takiego.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.constraint.ConstraintLayout>
</layout>

Wraz z tym sprawdź, czy nazwy zmiennych wiążących są poprawne, jak w klasie modelu widoku

3. Automatycznie wygenerowana nazwa klasy powiązania?

Klasa powiązania danych powinna zostać wygenerowana po utworzeniu układu powiązania.

Jeśli nazwa układ jest w przypadku węża activity_main.xml następnie klasy powiązania danych zostanie wygenerowany w przypadku wielbłądów podobnego ActivityMainBinding.

4. Nie widzisz sugestii importu?

Czasami podczas pisania ActivityMai..., to nie pokazuje sugestię , w tym przypadku importu ręcznie .

import <yourpackage>databinding.ActivityMainBinding;

5. Przeczytaj dziennik błędów kompilacji

Twoja klasa wiążąca i nowe zmienne w układzie nie zostaną wygenerowane, jeśli kompilacja się nie powiedzie. Więc najpierw Stwórz projekt przez Ctrl + F9 (Kompiluj> Utwórz projekt) .

  • Jeśli kompilacja się nie powiedzie, zobacz, co jest błędem, zwykle mamy błędy w polach układu. Dzienniki błędów wskażą numer wiersza błędu, w którym występuje problem.
  • Wiązanie może się nie powieść, powodując głupi błąd , taki jak błąd składni lub brak importu. W takim przypadku otrzymasz logcat pełen błędów związanych z klasami. Ale powinieneś przeczytać cały logcat, aby znaleźć odpowiedni problem .

6. Zamknij i otwórz projekt z ostatnich

Zawsze to robię, ponieważ zajmuje to znacznie mniej czasu niż Rebuild/ Makeproject.

  • Zamknij projekt z Plik> Zamknij projekt
  • Otwórz ponownie od ostatnich

Zauważ, że wolę Zamknij i Otwórz od ostatniego, ponieważ zajmuje to znacznie mniej czasu niż Rebuild / Restart IDE .

7. Przebuduj projekt

Jeśli nadal Twoja klasa nie jest generowana. (Jakiś czas, kiedy wklejamy plik układu, to się dzieje). Następnie Przebuduj projekt z Build> Rebuild( nie buduj ani nie twórz projektu ). Wygeneruje klasę powiązania danych. ( Rebuild robi dla mnie Magic. )

8. Miej najnowszą wersję Android Studio

Po aktualizacji AS do Android Studio 3.2 zauważyłem , że naprawiono wiele błędów w automatycznym generowaniu powiązań danych. Więc powinieneś mieć również najnowszy AS.

Rozwiązanie dla <variables

<data>
    <variable
        name="item"
        type="com.package.Model"/>
</data>

Zwykle, gdy umieszczamy zmienną w układzie, tworzy ona metodę pobierającą i ustawiającą. Możemy użyć binding.setItem(item);i binding.getItem();, ale jeśli nie widzisz tych metod, przeczytaj poniższe informacje.

1. Zamknij i otwórz projekt z ostatnich

Jeśli utworzyłeś zmienną danych - <variablew swoim układzie i nie pokazuje ona jej ustawiającego i pobierającego w klasie powiązania danych, wtedy Zamknij i Otwórz z ostatniego projektu.

2. Wyczyść projekt po zmianie typu

Jeśli zmieniłeś typ jakiegoś <variablew swoim układzie i typ ustawiacza metody pobierania się nie zmienia, to Wyczyść projekt ( Build> Clean Project)

Ostatnie słowa

Wreszcie, jeśli nadal nie jest generowana klasa wiążąca, mamy naszą najpotężniejszą broń. - Uruchom ponownie Android Studio: D.

  • Najpierw spróbuj ponownie uruchomić , to zawsze generuje zmienne mojego układu powiązań po ponownym uruchomieniu.
  • Jeśli to nie zadziała, unieważnij pamięć podręczną i uruchom ponownie .

To wszystko, co robię, aby rozwiązać błędy związane z wiązaniem danych. Jeśli pojawią się dalsze problemy, możesz skomentować tutaj.

Khemraj
źródło
2
Jeśli problem będzie się powtarzał ... (8) Unieważnij i uruchom ponownie ... jeśli nie zostanie rozwiązany, (9) zmień dataBinding {enabled = false} ... buduj, a następnie dataBinding {enabled = true} buduj ponownie ....
PravyNandas
1
W moim przypadku musiałem ręcznie zaimportować ścieżkę klas z jakiegoś powodu IDE nie pokazuje tego jako rozwiązania. Tnx :)
Ivan Kaloyanov
2
Uratowałem mój dzień. Brakowało zawijania <layout> w moim pliku układu. Dziękuję Ci!
Juliano
Możesz również dodać, że plik „import android.R” musi zostać usunięty, jeśli jest częścią listy importu. To rozwiązało mój problem z nierozwiązanym odwołaniem do pliku XML aktywności
Tim John
23

Klasa DataBinding wygenerowana automatycznie.

jeśli nazwa xml to activity_test, wówczas klasą Binding będzie ActivityTestBinding.

ale,

dataBinding {
        enabled = true
    }

układ powinien mieć układ główny

<layout xmlns:android="http://schemas.android.com/apk/res/android">
</layout>
ViramP
źródło
Godzinami szukam soultion, robię dużo magii gradle, ale używam ConstraintLayoutjako korzenia. Dziękuję Ci!
Alexey Markov
14

Miałem ten sam problem. Po przeczytaniu dokumentacji SDK systemu Android można utworzyć tylko oczekiwaną nazwę pliku, ale nie ma nic o tym, co zrobić, jeśli tak się nie stanie. Po kilku dalszych badaniach zauważyłem, że po usunięciu przestrzeni nazw do elementu układu, jak poniżej (na twoim przykładzie), zadziałało.

    <?xml version="1.0" encoding="utf-8"?>
    <layout>
        <data>  </data>
        <RelativeLayout
           xmlns:android="http://schemas.android.com/apk/res/android"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
        </RelativeLayout>
    </layout> 
ngaspama
źródło
10

W moim przypadku klasa Binding została wygenerowana i zainstalowana (ale myślałem, że tak nie jest) ... ale nie dodaje automatycznie importu tej klasy do sekcji importu aktywności / fragmentów ... więc ... OPCJA + WCHODZIĆ :)

Krzysztof Kubicki
źródło
2
Bingo, działało dla mnie, chociaż musiałem ręcznie wpisać import, inteligencja nie oferowała opcji z jakiegokolwiek powodu.
Rob
8

Po prawidłowym skonfigurowaniu go (w tym przestrzeni nazw xml i zawinięciu wszystkiego w <layout>), tym, który działał dla mnie, było budowanie -> Utwórz projekt. Ani Clean Project ani Rebuild Project nie. Pracuję w Android Studio 2.3.1 i używam narzędzi do kompilacji 26.0.2. Nie ma potrzeby stosowania <data>tagów.

Xtreme Biker
źródło
Powinno to być oznaczone jako poprawna odpowiedź. Reszta to tylko obejścia. Nie ma potrzeby przenoszenia przestrzeni nazw ani nawet dodawania elementu danych
Vicky Kapadia,
8

jeśli wykonujesz zadanie podstawowe, aby włączyć databainding w swoim projekcie, np. użyj opcji enable w gradle i użyj znacznika układu w xml , kiedy zmienisz kod xml i nie wygenerujesz nowej klasy wiązania danych dla tych xml, możesz użyć szybkiego sposobu generowania samych danych bindowanie klasy w gradle-> inne-> databindinggenbaseclassesDebuguj go szybciej niż buduj cały projekt. generuje tylko klasę wiązania danych. wprowadź opis obrazu tutaj

Mahdi Azadbar
źródło
4
dataBinding {
        enabled = true
    }

Aby włączyć nowy kompilator powiązań danych, dodaj następującą opcję do pliku gradle.properties:

android.databinding.enableV2=true
Samir Mangroliya
źródło
3

Klasy powiązań danych są generowane podczas kompilacji, więc po włączeniu powiązania danych w kompilacji Gradle aplikacji i otoczeniu pliku XML tagiem układu należy ponownie skompilować aplikację. Jeśli to nie pomoże, usuń folder kompilacji i zrób to ponownie.

Schadenfreude
źródło
2

Nie wiem, czy to zadziała, czy nie. Po prostu zmień nazwę pliku XML układu. Przypuśćmy, że nazwa układu to activity_main.xml, po prostu zmień nazwę na dowolną, taką jak main.xml i ponownie zmień nazwę na activity_main.xml . Następnie możesz zobaczyć opcję importu w ActivityMainBinding .

Mam nadzieję, że to działa dla Ciebie.

Sudhansu
źródło
pracował dla mnie: D
latifalbr
2

Dzięki tej odpowiedzi tutaj - wygląda na to, że „przestrzeń nazw układu” musi zostać wyczyszczona lub potrzebujesz nowej unikalnej nazwy.

Oto opcje, które zadziałały dla mnie:

  1. Utwórz nową nazwę układu, aby upewnić się, że można go wygenerować. To rozwiązało mój problem, w którym miałem układ, który został utworzony jako pierwszy, bez wiązania danych - nazwijmy to fragment_abc.xml. Kiedy próbowałem dodać do niego powiązanie danych, nie zostało ono rozpoznane - nawet po wielu czyszczeniach pamięci podręcznej i ponownym uruchomieniu. Jednak gdy tylko wykonałem kopię układu fragment_abc2.xml, natychmiast otrzymałem wygenerowany obiekt wiążący dane .java / .class.

  2. Po obejrzeniu powyższej pracy próbowałem po prostu usunąć folder / build z modułu i przebudować projekt - to działało, aby uzyskać powiązanie danych dla oryginalnego układu.

Gene Bo
źródło
1

Jedyną rzeczą, jaką mogę sobie wyobrazić, jeśli to możliwe, jest to, że nie masz

dataBinding {
    enabled true
}

w pliku ocen. Jeśli nie, po prostu dodaj go do pliku gradle. to znaczy

android {
  ......

  dataBinding {
    enabled true
  }
}

następnie zsynchronizuj swój projekt. Jeśli nadal się nie powiedzie, może być konieczne unieważnienie / ponowne uruchomienie studia Android

Hassan Semiu Ayomon
źródło
Wyraźnie wspomniałem w swoim pytaniu, że po dodaniu <variable>w xml generuje klasę Binding, więc nie ma przypadku nie dodawania dataBindingw pliku gradle, jeśli nie dodałem, to nie powinno generować klasy powiązania.
Ravi
Przed synchronizacją i ponownym uruchomieniem. Spróbuj wykonać „Make”. Ułóży się.
Nizamudeen Sherif
1

Podczas pracy z wielomodułową aplikacją na Androida sprawdź ścieżkę klasy powiązań. Może powinieneś użyć:

import com.yourcompany.app.android.modulename.databinding.FragmentABCtBinding zamiast:

import com.yourcompany.app.android.databinding.FragmentABCtBinding

kosiara - Bartosz Kosarzycki
źródło
1

Usuń układy i cofnij, a następnie upewnij się, że wygenerowane klasy powiązań zostały poprawnie zaimportowane.

Ahmed AlAskalany
źródło
1

Moim rozwiązaniem było przyjęcie jako przyrostka FragmentBinding w nazwie klasy.

Klasa powiązania jest generowana dla każdego pliku układu. Domyślnie nazwa klasy jest oparta na nazwie pliku układu, konwertując go na wielkość liter Pascal i dodając do niego przyrostek Binding. Powyższa nazwa pliku układu to activity_main.xml, więc odpowiadająca wygenerowana klasa to ActivityMainBinding. Ta klasa przechowuje wszystkie powiązania z właściwości układu (na przykład zmienną użytkownika) do widoków układu i wie, jak przypisać wartości do wyrażeń powiązań.

Nazewnictwo nazwy aktywności lub klasy fragmentów może różnić się pod względem przedrostków. Ponieważ przyrostek jest zawsze Binding.

Po wykonaniu odpowiedzi Khemraj i Invalidate Caches / Restart , należy przepisać ActivityBinding lub FragmentBinding, aby uzyskać sugestie IDE klas, które zostały już wygenerowane, i NIE Koduj na stałe importu.

W moim przypadku próbowałem zaimportować nazwę klasy do tyłu be FragmentCompetitionsBindingzamiast CompetitionsFragmentBinding.

GL

Źródło

Braian Coronel
źródło
1
to działa dla mnie.
Nouman Ch
1

Jeśli odpowiedź nie zadziałała, to moja rekomendacja jest prosta, ale skuteczna.

Chodzi o to, aby określić, który komponent powoduje problem. Aby to zrobić, skomentuj wszystkie swoje linie custom_fragment.xmli ich zastosowania w CustomFragment.kti zostaw coś minimalistycznego, takiego jak poniżej.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</layout>

Następnie uruchom aplikację i dodaj komponent do komponentu podczas Apply Code Changes(Ctrl + Alt + F10) do wykonywania aplikacji, aż aplikacja ulegnie awarii, czyli wtedy, gdy znajdziesz usterkę.

Dzienniki powiązań danych czasami nie są tak opisowe i jest to ogólna strategia znajdowania wadliwego składnika.

GL

Braian Coronel
źródło
0

Miałem ten sam problem. Wszystko, co zrobiłeś poprawnie. Chodzi o to, że musisz dodać zmienną wewnątrz znacznika danych w xml. W tym celu należy utworzyć przykładową klasę modelu i dodać ją jako zmienną w znaczniku danych.

Do tego czasu nie zobaczysz wygenerowanego ActivityMainBinding.

Srinivasan
źródło
0

Miałem podobny problem, w którym miałem opakowany układ i włączone wiązanie danych w pliku gradle. Główna działalność nadal nie mogła zrozumieć ani zobaczyć moich zajęć. Naprawiło to, że dodałem zmienną powiązania i mimo to zaimportowałem powiązanie. Stamtąd właśnie zbudowałem rozwiązanie, a potem wydawało się, że wiem, jaka jest klasa. Stamtąd mogłem zaimportować wygenerowane przeze mnie klasy skrzynek wielbłądów.

stegnerd
źródło
0

Pojawił się problem i problem dotyczył układu, którego użyto pola nie było ciągiem, lecz datą.

Wygląda na to, że wszystkie pola muszą być tekstowe, przynajmniej z komponentem TexView.

Jeśli budujesz za pomocą polecenia ./gradlew build --stacktrace

To lepiej pokazuje błędy.

jactive
źródło
0

W moim przypadku pomyślałem, że wygenerowana klasa musi pojawić się z moimi zwykłymi klasami w srcfolderze. Dodatkowo pomyślałem, że nazwa generowanej klasy powinna być nieco inna. To wszystko był mój błąd. Wygenerowaną klasę można znaleźć w buildfolderze build -> generated -> ...ścieżka. Jeśli w Twoim działaniu nie ma importu wygenerowanej klasy, dodaj import

import com.yourcompany.app.databinding.ActivityMainBinding;"
Kseniya
źródło
0

W przypadku wystąpienia następującego błędu w DataBindingUtil.setContentView

Nierozwiązane odniesienie: activity_main

wszystko, co musisz zrobić, to usunąć następującą instrukcję importu

import android.R

Rozwiązanie znalazłem na innym forum. Źródło

Tim John
źródło
0

Jeśli ostatnio któryś z nich przeprowadził migrację istniejącego projektu do androidx , musisz zastąpić import z

import com.yourpackagename.BR;

do

import androidx.databinding.library.baseAdapters.BR;

Po 2 dniach Google w końcu dostałem rozwiązanie, które działa dla mnie.

Milan Sheth
źródło
1
Nie. Zasób wiążący ( .BR. ), Taki jak zasób ( .R. ). Został wygenerowany na podstawie zasobu projektu (identyfikator, do rysowania, kolor, ...), więc zostanie umieszczony w pakiecie projektu ( your.project.package.BR). Nie w bibliotece innej firmy, takiej jak androidx.databinding.library.baseAdapters.BR.
dphans
0

Istnieją przypadki, gdy nie zobaczysz pliku w wygenerowanym katalogu, możesz wiązać właściwość, która nie jest zadeklarowana w ViewModel. Zasadniczo nie powoduje to błędu lint, jeśli zrobisz to w xml.

Uzair
źródło
0

Jeśli implementujesz Serializable -> musisz zaimplementować Serializable

inaczej otrzymasz ten błąd. Mam nadzieję, że pomoże to komuś w przyszłości

W moim przypadku korzystam z biblioteki Parcel. Brakowało mi adnotacji @Parcel w mojej podklasie

Ranjith Kumar
źródło
0

Oprócz powyższych kroków możesz również sprawdzić typ zmiennej. Upewnij się, że jest to ciąg dla TextView lub taki sam, jak zdefiniowano w BindingAdapter. Na przykład:

data class MyDataObject(val name: String, val age: Int)

iw XML:

android:text="@{dataobject.age}"

Spowoduje to powyższy błąd. Aby to naprawić, możesz utworzyć zmienną wieku typu String lub możesz zaimportować String do swojego XML i użyć String.valueOf(age)w następujący sposób:

<data>
    <import type="String" />
...
</data>

A w Twoim TextView:

android:text="@{String.valueOf(dataobject.age)}"
nieśmiały
źródło
0

W moim przypadku klasy powiązań danych nie zostały wygenerowane, ponieważ usunąłem katalog zasobów systemu Android mipmap. Ponownie utworzyłem katalog res / mipmap /, a klasy powiązań danych zostały przywrócone.

buggily
źródło
0

Napotkałem podobny problem, w którym DataBinding nie mógł wygenerować klasy BindingImpl . W moim przypadku był to problem z metodą w klasie danych, gdzie nazwa została użyta nieprawidłowo: Model zawierał metodę onSignInCliked () iw układzie, którego użyłem onSigninCliked () . Zauważyć signin vs signin .

Komunikat o błędzie nie był wystarczający i odkryłem problem tylko wtedy, gdy użyłem skryptu kompilacji z opcją śledzenia stosu.

Ionut Negru
źródło
0

Upewnij się, że powiązanie danych jest włączone

android {
...
   dataBinding {
        enabled = true
    }
...
}

Synchronizuj projekt z Gradle dan kliknij przycisk (Synchronizuj projekt z Gradle)

fahrizal89
źródło
0

Jeśli istnieje problem z plikiem XML, klasa Databinding nie zostanie wygenerowana. Szybkim rozwiązaniem byłoby przejrzenie pliku XML i sprawdzenie błędów składniowych (które zwykle są podświetlone na czerwono). Błędy mogą przybrać formę nieistniejących lub błędnych odniesień, błędów typograficznych itp.

Krótko mówiąc, upewnij się, że w kodzie XML nie ma podkreślonej na czerwono linii. Kiedy skończysz, odbuduj i Twoja klasa Databinding zostałaby wygenerowana.

Taslim Oseni
źródło
-1

1. Dodaj poniżej w gradle aplikacji

 dataBinding {
        enabled = true
    }

W układzie xml napisz poniższy kod

<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
  <data></data>
</layout>if you don't get data binding class just rename the layout file name and you will get data binding class.
Rohan Lodhi
źródło
3
Dlaczego w ogólnym przypadku dataBinding wymagałoby pozwolenia internetowego?
M.Pomeroy
1
@ M.Pomeroy tak to nie jest wymagane, nie edytowałem odpowiedzi dzięki
Rohan Lodhi
-5

użyj ścieżki klasy „com.android.databinding: dataBinder: 1.0-rc0”

Sumanta Banerjee
źródło
w przypadku klasy 1.5.0 i nowszych nie ma potrzeby używania tej ścieżki klas.
Ravi