问题
I am trying to use MVVM pattern with android databinding. I have an edittext and a textview that should show the same text when I type in the edittext field by binding to the model via the observablefield with a LocationType model object.
From testing both fields are set to "hello" when I start the app, as expected. But when I type in the edittextfield the textview does not update, even tough the model object gets updated correctly as can be seen with by debug.
When I use an:
observablefield<String>
drop using the model and just set to some text and update the xml to use this field. It works as intended.
model:
public class LocationType {
private String locationType;
public String getLocationType() {
return locationType;
}
public void setLocationType(String locationType) {
this.locationType = locationType;
}
}
modelView:
public class LocationTypeViewModel extends BaseObservable {
@Bindable
private ObservableField<LocationType> locationTypeObservableField = new ObservableField<>();
private Context context;
LocationType locationType;
public LocationTypeViewModel(Context context) {
this.context = context;
locationType = new LocationType();
locationType.setLocationType("Hello");
locationTypeObservableField.set(locationType);
}
public ObservableField<LocationType> getLocationTypeObservableField() {
Log.d("CALLED GET", locationType.getLocationType());
return locationTypeObservableField;
}
}
XML:
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<variable
name="viewModel"
type="fragment.LocationType.viewmodel.LocationTypeViewModel"/>
</data>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="@{viewModel.locationTypeObservableField.locationType}"
android:id="@+id/edittext1"/>
<TextView
android:layout_below="@+id/edittext1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="@{viewModel.locationTypeObservableField.locationType}"
android:id="@+id/text"
/>
</RelativeLayout>
</layout>
回答1:
android:text="@={viewModel.locationTypeObservableField.locationType}"
You forgot to add "=" .check and compare above line with your code.
回答2:
Two way databinding should be like this android:text="@={ProfileViewModel.mobileNumber}" You forgot to add "="
回答3:
The problem is you are observing changes to the field inside LocationTypeViewModel
which points to a LocationType
object. That will only notify changes when the object reference changes. What you want is an observer on the actual String
field.
You are also missing an important two-binding symbol on your EditText
. You want to use @={obj.fieldName}
instead of @{obj.fieldName}
. The @= signals that you want changes to propagate back to the source.
Here is your code edited to work as intended:
public class LocationType {
private String location;
public LocationType(String location) {
this.location = location;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
public class LocationTypeViewModel extends BaseObservable {
private final LocationType locationType;
public LocationTypeViewModel() {
locationType = new LocationType("Hello");
}
@Bindable
public String getLocation() {
return locationType.getLocation();
}
public void setLocation(String location) {
locationType.setLocation(location);
notifyPropertyChanged(BR.location);
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<variable
name="viewModel"
type=".LocationTypeViewModel"/>
</data>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="@={viewModel.location}"
android:id="@+id/edittext1"/>
<TextView
android:layout_below="@+id/edittext1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="@{viewModel.location}"
android:id="@+id/text"
/>
</RelativeLayout>
</layout>
来源:https://stackoverflow.com/questions/45640618/android-two-way-databinding-textview-not-updating