Reputation: 5196
I have a parent class, lets call it BaseViewModel, this class can be typed and have an ObservableField of the same type. Like this :
public class BaseViewModel<T> extends BaseObservable {
ObservableField<T> value = new ObservableField<>();
public T getValue() {
return value.get();
}
public void setValue(T value) {
this.value.set(value);
setHasChanges(value != originalValue);
}
}
I got many child for this class. One of them is StringViewModel that, like its name says, gives a String value. This child class overrides the setValue() method :
public class StringViewModel extends BaseViewModel<String> {
@Override
public void setValue(String value) {
this.value.set(value);
if(value != null && !value.isEmpty()){
setHasChanges(!value.equals(originalValue));
}
else if(originalValue == null)
setHasChanges(false);
else
setHasChanges(!originalValue.isEmpty());
}
//Other methods ...
}
And I got a layout that use a StringViewModel :
<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">
<data>
<variable
name="viewModel"
type="com.myproject.viewmodels.StringViewModel" />
</data>
<EditText
android:id="@+id/value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="@{viewModel.editable}"
android:cursorVisible="@{viewModel.editable}"
android:ellipsize="end"
android:focusable="@{viewModel.editable}"
android:focusableInTouchMode="@{viewModel.editable}"
android:inputType="textMultiLine|textNoSuggestions"
android:text="@={viewModel.value}"
app:setError="@{viewModel.error}"
tools:text="Dupont" />
<!-- Other layouts ... -->
But when I call the setValue() method of my StringViewModel, the value is set to the ViewModel but not on the EditText.
Edit : I should also say that I've add my StringViewModel to my DataBinding correctly (using DataBindingUtil to inflate my DataBinding).
myDataBinding.setViewModel(new StringViewModel());
Does someone got an explanation to this behavior?
EDIT
As @iMDroid said, I should have call notifyChange()
in my method setValue()
. I tought ObservableFields was doing it for me, my bad.
Upvotes: 4
Views: 2417
Reputation: 2128
I am not expert in two-way data binding.. but I have been reading articles about it so here is one solution which might help you.
Suppose your model class is this:
public class Echo {
public String text;
}
And your layout file is R.layout.echo
They say you are supposed to set the layout using the DataBindingUtil class and then the object on which you make the binding that is EchoBinding (automatically generated according to the layout) like this:
EchoBinding binding = DataBindingUtil.setContentView(
this, R.layout.echo);
binding.setEcho(new Echo());
Also, you can bind the value to your EditText using app:binding="@{echo.text}"
attribute.
<EditText
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:hint="Text 1"
app:binding="@{echo.text}"/>
And lastly add notifyChange()
to your setValue()
method.
Refer to this link for more information.
You may give it a try.. Hope it helps.
Upvotes: 2
Reputation: 129
Adding the StringViewModel to the layout is not enough. In the onCreate() or onCreateView() depending on which you are using(Activity or Fragment), you have to tell your dataBinding to use the defined StringViewModel class.
in onCreate(), you want to do something like,
dataBinding.viewModel = new StringViewModel();
now, the dataBinding knows what you mean and they are now connected.
I believe you have setup the dataBinding.
Upvotes: 0