Ошибка Android DataBinding. Не удалось найти аксессуар

Я получаю следующую ошибку при попытке запуска моего приложения:

Error:Execution failed for task ':app:compileDevelopmentDebugJavaWithJavac'.
> java.lang.RuntimeException: Found data binding errors.
****/ data binding error ****msg:Could not find accessor java.lang.String.giftRecipientName redacted.xml loc:182:63 - 182:93 ****\ data binding error ****

У меня есть объект Order, который выглядит следующим образом:

public class Order {
    public Address address;
    // unrelated fields and methods
}

Вложенный адресный объект выглядит следующим образом:

public class Address {
    public String addressLine1;
    public String addressLine2;
    public String giftRecipientName;
    public Boolean isGift;
}

В моем .xml я делаю следующее:

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

    <data>
        <variable name="order" type="example.redacted.models.Order"/>
    </data>
    // widgets and whatnot
    <TextView
        android:id="@+id/gift_recipientTV"
        android:layout_column="1"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:textStyle="bold"
        android:gravity="right"
        android:text='@{order.address.isGift ?  order.address.giftRecipientName : "" }'/>

Наконец, в моем фрагменте:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    RedactedBinding dataBinding = DataBindingUtil.inflate(inflater, R.layout.redacted, container, false);
    dataBinding.setOrder(_order);
    return dataBinding.getRoot();
}

Ответ 1

После нескольких часов проб и ошибок кажется, что привязка данных Android привязана к геттерам до того, как она увидит публичные поля. Объект My Order имел вспомогательный метод getAddress

public class Order {
    public Address address;

    public String getAddress() {
        return address.addressLine1 + address.addressLine2;
    }
}

Связывание вызывало этот метод вместо доступа к общему адресу. Я поместил метод getAddress в объект Address (где он, вероятно, должен был начаться) и скомпилированное приложение.

Ответ 2

  Ошибка привязки данных Android. Не удалось найти аксессор

  • Как говорит эта ошибка, для работы привязки требуется accessor или getter, а также setter, если вы используете двустороннюю привязку.
  • Поэтому всегда ставьте getter & setter в вашем модельном классе.

Ответ 3

Проверьте свой файл макета и класс ViewModel. Имя переменной должно быть одинаковым в обоих файлах. Просто так:

В классе ViewModel:

MutableLiveData<String> emailId = new MutableLiveData<>();

В файлах макетов:

<EditText
     ........
      android:text="@={loginVM.emailId}"

Ответ 4

В моем случае My ViewModel имеет имя переменной, начинающееся с m, и это создавало проблему

public class MyViewModel extends ViewModel {
    private LiveData<SomeClass> mTask; //Chaning the variable name to task and it getter name to getTask worked for me
    //...code left for brevity
    public LiveData<SomeClass> getmTask() {
        return mTask;
    }
}

Я изменил имя переменной mTask на task, а имя получателя getmTask - на getTask, и это сработало для меня.

public class MyViewModel extends ViewModel {
    private LiveData<SomeClass> task;
    //...code left for brevity
    public LiveData<SomeClass> getTask() {
        return task;
    }
}

И в моем XML файле я смог получить к нему доступ

<TextView
    ...
    android:text="@{viewmodel.task.title}"

Ответ 5

В моем случае я обращался к свойству объекта kotlin из xml:

object CurrentUser {
    // ...
    var userTeams: Map<String, String> = //...
    // ...
}
<Button
   android:text="@{CurrentUser.userTeams.get("id")}" />

но поскольку привязка данных использует Java, он не может напрямую обращаться к объекту Kotlin, поэтому я изменил его на:

<Button
   android:text="@{CurrentUser.INSTANCE.userTeams.get("id")}" />

И это работает!

Ответ 6

В моем случае это был тот факт, что я использовал не тот объект все вместе. Я использовал:

      <variable
        name="searchResults"
        type=".SearchResults" />

Вместо:

      <variable
        name="searchResults"
        type=".SearchViewModel" />