I want to use a custom @BindingAdapter to set the text of a TextView using LiveData.
TextView:
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
app:keyToText='@{viewmodel.getText("TI_001")}'/>
BindingAdapter:
@BindingAdapter("keyToText")
public static void setTextViewText(TextView tv, LiveData<String> data) {
if (data == null || data.getValue() == null) {
tv.setText(null);
} else {
tv.setText(data.getValue());
}
}
Using the debugger, I already checked that the data object holds the correct value, which it does:
But unfortunately data.getValue() always returns null, so the text isn't set to the provided TextView.
Am I missing something? I really need this to work this way... hopefully.
UPDATE
The lifecycleowner is set to the binding as followed:
mBinding.setLifecycleOwner(this);
When I use
viewModel.getText("TI_001").observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
tv.setText(s);
}
});
I can read the value of observed LiveData without any problems.
UPDATE 2
Viewmodels getText method:
public LiveData<String> getText(String key){
return textRepository.getText(key);
}
textRepository's getText method:
public LiveData<String> getText(String id){
return textDao.findById(id);
}
And textDao's findById method:
@Query("SELECT text.text FROM text WHERE text.id LIKE :id")
LiveData<String> findById(String id);
I might have found a solution for my problem:
@BindingAdapter("keyToText")
public static void setTextViewText(TextView tv, LiveData<String> data) {
if (data == null) {
tv.setText(null);
} else {
data.observeForever(new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
tv.setText(data.getValue());
data.removeObserver(this);
}
});
}
}
So I'm basically observing my LiveData only for the first onChanged event and removing the used observer right after setting the text.