I am using an AsyncTask in my repository which is used to set the LiveData in the repository. How do I observe this LiveData from my ViewModel using Transformations?
You can ignore my other answer. The solution is using MediatorLiveData<> in your view model. You add the LiveData from the repository as a data source to the MediatorLiveData<> and call setValue or postValue (depends on if it is in the UI tread or not) in the observer onChanged callback.
Like so
currentTransaction.addSource(application.getFinanceRepository().getTransaction(id),
new Observer<Transaction>() {
@Override
public void onChanged(@Nullable Transaction transaction) {
//Updates the MediatorLiveData<> that you activity is observing
currentTransaction.setValue(transaction);
}
});
So I was trying just this thing today and couldn't get it to work. I tried both
Transformations.switchMap(application.getFinanceRepository().getTransaction(id),
new Function<Transaction, LiveData<Transaction>>() {
@Override
public LiveData<Transaction> apply(Transaction input) {
Log.d(TAG, "apply: VIewModel Transaction changed: " + input.toString());
//Set the inital transaction to track changes
initialTransaction = input;
//Update the transaction observed by the activity/fragment
currentTransaction.setValue(input);
return currentTransaction;
}
});
and
Transformations.map(loading,
new Function<Transaction, Object>() {
@Override
public Object apply(Transaction input) {
//Set the inital transaction to track changes
initialTransaction = new Transaction(input);
//Update the transaction observed by the activity/fragment
currentTransaction.setValue(input);
return null;
}
});
where currentTransaction is a MutableLiveData and initalTransaction is just a Transaction object. application.getFinanceRepository().getTransaction(id) returns a LiveData
This compiled fine but didn't run properly. apply() was never called and I was left with a null Transaction. I couldn't figure out how to get it to load something.
As a work around to get it working I returned application.getFinanceRepository().getTransaction(id) back to the fragment/activity. The observer for this would then call a method in the viewModel to give Transaction back to the view model
public void transactionLoaded(Transaction transaction) {
initialTransaction = new Transaction(transaction);
currentTransaction.setValue(transaction);
}
I then also set the activity to also observe currentTransaction the MutableLiveData
Some more snippets to hopefully clear up what I did.
viewModel.loadTransaction(id).observe(this, new Observer<Transaction>() {
@Override
public void onChanged(@Nullable Transaction transaction) {
viewModel.transactionLoaded(transaction);
}
});
viewModel.getTransaction().observe(this, new Observer<Transaction>() {
@Override
public void onChanged(@Nullable Transaction trans) {
//When new LiveData arrives update the transaction and then the views
Log.d(TAG, "onChanged: transaction changed: " + trans.toString());
transaction = trans;
updateViews();
}
});
private Transaction initialTransaction;
private final MutableLiveData<Transaction> currentTransaction = new MutableLiveData<>();
public LiveData<Transaction> loadTransaction(int id) {
return application.getFinanceRepository().getTransaction(id);
}
public void transactionLoaded(Transaction transaction) {
initialTransaction = new Transaction(transaction);
currentTransaction.setValue(transaction);
}
It isn't ideal because it won't work unless the fragment/activity participates but it does function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.