ObservableField Value Inside ViewModel Does Not Update UI With Data Binding
ObservableField<Marker>
value inside ViewModel
class value is changed using EditText
in layout however value is not propagated to TextView tv_summary
.
This is the layout
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="com.example.tutorial5livedata_mvvm_room_recyclerview.util.BindingUtils"/>
<variable
name="viewModel"
type="com.example.tutorial5livedata_mvvm_room_recyclerview.viewmodel.AddMarkerViewModel"/>
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Title"
android:textColor="#FC7100"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:ems="10"
android:hint="Title"
android:inputType="textPersonName"
android:text="@={viewModel.markerObservableField.title}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
<TextView
android:id="@+id/tv_latitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Latitude"
android:textColor="#FC7100"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
app:layout_constraintTop_toBottomOf="@+id/et_title" />
<EditText
android:id="@+id/et_latitude"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:ems="10"
android:hint="Latitude"
android:text="@={viewModel.markerObservableField.latitude}"
android:inputType="number"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline_left"
app:layout_constraintTop_toBottomOf="@+id/tv_latitude" />
<TextView
android:id="@+id/tv_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text='@{viewModel.markerObservableField.title + " " + viewModel.markerObservableField.latitude}'
app:layout_constraintStart_toStartOf="@+id/guideline_left"
app:layout_constraintTop_toBottomOf="@+id/et_latitude" />
<android.support.constraint.Guideline
android:id="@+id/guideline_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="8dp" />
</android.support.constraint.ConstraintLayout>
</layout>
ViewModel class
public class AddMarkerViewModel extends AndroidViewModel {
private MarkerRepository mMarkerRepository;
public ObservableField<Marker> markerObservableField = new ObservableField<>();
public AddMarkerViewModel(@NonNull Application application) {
super(application);
AppDatabase appDatabase = AppDatabase.getInstance(application.getApplicationContext());
mMarkerRepository = MarkerRepository
.getsInstance(MarkerLocalDataSource.getInstance(appDatabase.markerDao(), new AppExecutors()));
if (markerObservableField.get() == null) {
Marker marker = new Marker();
marker.setTitle("New Title");
markerObservableField.set(marker);
}
}
public long addMarker(Marker marker) {
return mMarkerRepository.addMarker(marker);
}
}
onCreate method of Activity for adding marker to set values
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_add_marker);
mAddMarkerViewModel = ViewModelProviders.of(this).get(AddMarkerViewModel.class);
mBinding.setViewModel(mAddMarkerViewModel);
}
Answer
In order to listen to property changes, you will need to extend BaseObservable
.
I think the problem here is that property change does not fire event, because you listen to Field change, that is marker object itself, that stays same.
Marker
field Latitude
is not observable, that means it's impossible to detect it's change.
You have two options.
If you want to detect changes, you can create observable field for Latitude.
public ObservableField<String> latitudeObservableField = new ObservableField<>();
You can listen to field Changes and update marker object.
latitudeObservableField.addOnPropertyChangedCallback(() -> {
// Update marker object
})
Another approach would be to make Marker
extend BaseObservable
, like explained in attached reference.
Please check out official documentation on observable objects.
Related Questions
- → should I choose reactjs+f7 or f7+vue.js?
- → Phonegap Android write to sd card
- → Local reference jquery script in nanohttpd (Android)
- → Click to navigate on mobile devices
- → How to allow api access to android or ios app only(laravel)?
- → Access the Camera and CameraRoll on Android using React Native?
- → React native change listening port
- → What is the default unit of style in React Native?
- → Google play market autocomplete icon
- → Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `ListView`
- → Using Laravel with Genymotion
- → react native using like web-based ajax function
- → react native pdf View