0

(French here, sorry for potential misunderstandings)

I am new to databinding on Android and I am struggling with a rather simple issue.

Let's say I have this POJO which we will consider as part of my Model

public class User
{
    public String name;

    public User(String name)
    {
        this.name = name;
    }
}

Now I have a ViewModel that contains a User

public class MyViewModel extends ViewModel
{
    private User user = new User("blue");

    public String getName()
    {
        return user.name;
    }

    public void setName(String name)
    {
        user.name = name;
    }
}

I want the View (Activity) to be able to make a two-way databinding on this "name" field. I know how to do the Activity and XML stuff like seting up the Binding class etc. What I don't know is, how to make the ViewModel observable for any change on the "name" field of the User class. Note that I don't want to make my User class observable by doing :

public class User
{
    public MutableLiveData<String> name;

    public User(String name)
    {
        this.name.setValue(name);
    }
}

because I personally prefer keeping this Android stuff away from my Model.

How can I change my ViewModel so that the View can listen to changes of "name" ? I've seen some things with the @Bindable annotation but I'm not quite sure on how to use it.

Thanks for your help

Charly Lafon
  • 562
  • 1
  • 3
  • 18

2 Answers2

0
You can add Bindable like this in your POJO Class

public class User extends BaseObservable
{
  public String name;
  public User(String name)
  {
    this.name = name;
  }

 @Bindable
 public String getName() 
 {
    return name;
 }

 public void setName(String name)
 {
    this.name = name;
    notifyPropertyChanged(BR.name);
}
}
yash786
  • 1,151
  • 8
  • 18
0

In your layout file you'd have something like:

<data>
    <variable name="vm" type="<your_package>.MyViewModel" />
</data>

You then might have something like TextView that binds to name using:

        <TextView
            android:id="@+id/name"
            android:text="@{vm.name}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

One other important thing you need to do is call following in your activity/fragment:

binding.setLifecycleOwner(this)

(along with binding.vm = yourViewModelInstance)

John O'Reilly
  • 10,000
  • 4
  • 41
  • 63
  • So I won't have to use any LiveData or ObservableFields in the ViewModel ? I'm updating Android Studio right now, I'll see if it works but it surprises me haha – Charly Lafon Jan 06 '19 at 18:56
  • ah, I missed that you were't using `LiveData` in your `ViewModel`...yeah, the above would be based on using that – John O'Reilly Jan 06 '19 at 20:13
  • @CharlyLafon is there reason you can't have something like a `MutableLiveData` in your `ViewModel` ? – John O'Reilly Jan 06 '19 at 20:23
  • No filling the ViewModel with Android binding stuff is cool. I don't want to touch the User class that's all. So you think making the user field a MutableLiveData is the solution (sorry I still can't try your answers, my android studio is struggling to update) ? I thought it wouldn't work because I want to listen to changes of the "name" field of user, not changes to user itself. – Charly Lafon Jan 06 '19 at 20:26
  • You could also have a `MutableLiveData` in your `ViewModel` if just want to manage just the name string but I think having it for `User` might be more flexible. In your layout then you should be able to bind to something like `vm.user.name` – John O'Reilly Jan 06 '19 at 20:30