34

I'm getting the following error when I try to run my app:

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

I have an Order object which looks like this:

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

The nested Address object looks like this:

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

In my .xml I am doing the following:

<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 : "" }'/>

Lastly in my fragment:

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();
}
MidasLefko
  • 4,499
  • 1
  • 31
  • 44

11 Answers11

39

After hours of trial and error it seems that Android data-binding looks for getters before it looks at public fields. My Order object had a helper method called getAddress

public class Order {
    public Address address;

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

The binder was calling that method instead of accessing the public Address field. I put the getAddress method inside the Address object (where it probably should have been to begin with) and the app compiled.

MidasLefko
  • 4,499
  • 1
  • 31
  • 44
9

Android DataBinding error. Could not find accessor

  • As this error tells, binding needs accessor or getter to work and also setter if you use two way binding.
  • So always put getter & setter in your model class.
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
5

In my case, I was accessing a kotlin object's property from xml:

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

but as data binding uses Java, it can't access a Kotlin object directly, so I changed it to:

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

And it works!

aksh1618
  • 2,245
  • 18
  • 37
3

In my case, My ViewModel has a variable name starting with m and it was creating a problem

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

I changed the variable name mTask to task and it's getter name getmTask to getTask and it worked for me.

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

And In my xml file I was able to access it

<TextView
    ...
    android:text="@{viewmodel.task.title}"
Sanjeev
  • 4,255
  • 3
  • 28
  • 37
3

Check your Layout file and ViewModel class. A variable name should be the same in both files.just like:

In ViewModel class:

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

In Layout files:

<EditText
     ........
      android:text="@={loginVM.emailId}"
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
rahul
  • 37
  • 2
1

Please to change the parameter values private to public its will working

  • 3
    From Review: Hi, this post does not seem to provide a [quality answer](https://stackoverflow.com/help/how-to-answer) to the question. Please either edit your answer and improve it, or just post it as a comment. – sɐunıɔןɐqɐp Oct 22 '19 at 08:35
1

One of the reason for this can be just mistyped variable names. In my case, I have written

android:text="@={viewModel.authPhone.Phone}"

instead of

android:text="@={viewModel.authPhone.phone}"

You don't have to write or override getter and setter for the data class.

prsnlme
  • 179
  • 8
0

In my case, it was the fact that I was using the wrong object all together. I was using:

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

Instead of:

<variable
  name="searchResults"
  type=".SearchViewModel" />
Boken
  • 4,825
  • 10
  • 32
  • 42
BlackHatSamurai
  • 23,275
  • 22
  • 95
  • 156
0

My problem was the same as @Sanjeev. The class instance variable began with "m" (mUsername). However, the problem is not the name of the instance variable. The problem is the name of the getter. When I changed the getter from getmUserName() to getUserName(), it worked. I don't understand why the "m" in the getter name caused a problem.

Daniel Walker
  • 6,380
  • 5
  • 22
  • 45
mem100
  • 43
  • 1
  • 7
0

Ran into similar problem and spent a couple of hours on it.. We tried to implement StateFlow instead of LiveData and had a couple of Could not find accessor errors...

Our solution:

  • Upgrade Gradle Plugin from 4.2.2 to 7.* (JDK 1.8 -> JDK 11)
chrjs
  • 2,375
  • 1
  • 25
  • 41
0

late to the party, it may be that a particular variable is used in another Model class as its own class file. Search and see and if you can rename it. I had this issue.

Rohan
  • 841
  • 1
  • 11
  • 22