Как LiveData в ViewModel может наблюдать Livedata в репозитории с помощью трансформаций?
Я использую AsyncTask в моем хранилище, которое используется для установки LiveData в хранилище. Как мне наблюдать эти LiveData из моей ViewModel, используя Transformations?
2 ответа
Вы можете игнорировать мой другой ответ. Решение использует MediatorLiveData<> в вашей модели представления. Вы добавляете LiveData из хранилища в качестве источника данных к MediatorLiveData <> и вызываете setValue или postValue (зависит от того, находится ли он в протекторе пользовательского интерфейса или нет) в обратном вызове onChanged наблюдателя.
Вот так
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);
}
});
Так что сегодня я пробовал именно это и не мог заставить его работать. Я пробовал оба
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;
}
});
а также
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;
}
});
где currentTransaction - MutableLiveData, а initalTransaction - просто объект Transaction. application.getFinanceRepository().getTransaction(id) возвращает LiveData
Это скомпилировано нормально, но не работает должным образом. apply() никогда не вызывался, и я остался с нулевой транзакцией. Я не мог понять, как заставить это загрузить кое-что.
Чтобы обойти это, я вернул application.getFinanceRepository (). GetTransaction (id) обратно во фрагмент / действие. Наблюдатель для этого затем вызовет метод в viewModel, чтобы вернуть транзакцию обратно в модель представления.
public void transactionLoaded(Transaction transaction) {
initialTransaction = new Transaction(transaction);
currentTransaction.setValue(transaction);
}
Затем я также установил активность, чтобы также наблюдать currentTransaction MutableLiveData
Еще несколько фрагментов, чтобы, надеюсь, прояснить, что я сделал.
Fragment.java onActivityCreated ()
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();
}
});
TransactionViewModel.java соответствующие части
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);
}
Это не идеально, потому что это не будет работать, если фрагмент / деятельность не участвует, но он работает.