androidandroid-databindingbindable

Bindable not getting notified


@Bindable
public String getFirstName() { 
    return this.firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
    notifyPropertyChanged(BR.firstName);
}

@Bindable
public String getLastName() { 
    return this.lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
    notifyPropertyChanged(BR.lastName);
}


@Bindable({"firstName", "lastName"})
public void getName() { 
    return this.firstName + ' ' + this.lastName; 
}

Above code I picked up from Google's sample code - https://developer.android.com/reference/android/databinding/Bindable

And using it in XML like

<TextView
    android:id="@+id/first_name"
    .....
    android:text="@{myViewModel.firstName}" />
<TextView
    android:id="@+id/last_name"
    .....
    android:text="@{myViewModel.lastName}" />
<TextView
    android:id="@+id/full_name"
    .....
    android:text="@{myViewModel.getName()}" />

Whenever I am calling myViewModel.setFirstName("Mohammed"); it is updating the first name in view but not the full name. Even the documentations are buggy and not reliable.

Other posts related to this issue could not help much as most of them deal with non parameterised Bindables.

As per this line in doc

Whenever either firstName or lastName has a change notification, name will also be considered dirty. This does not mean that onPropertyChanged(Observable, int) will be notified for BR.name, only that binding expressions containing name will be dirtied and refreshed.

I also tried calling notifyPropertyChanged(BR.name); but it also has no effect on the result.


Solution

  • So after thorough analysis of databinding concepts, I found out that when we call notifyPropertyChanged on BaseObservable class it actually notifies the property but not the getters and setters.

    So in my question above, there are no changes in the JAVA part, but the change was required in XML part.

    <TextView
        android:id="@+id/first_name"
        .....
        android:text="@{myViewModel.firstName}" />
    <TextView
        android:id="@+id/last_name"
        .....
        android:text="@{myViewModel.lastName}" />
    <TextView
        android:id="@+id/full_name"
        .....
        android:text="@{myViewModel.name}" />
    

    Since I am declaring getName() as Bindable({"firstName", "lastName"}), databinding generates the property name so I have to listen for myViewModel.name instead of myViewModel.getName() in my XML. And we don't even have to notify name for change, notifying just the firstName or lastName will notify the property name because of parameterised Bindable.

    But make sure that the