问题
I have two livedatas. I need to take subtraction on them, but how to do it with two livedatas?
I've created something like this, but this is no proper way because it doesn't refresh result always when I need it.
totalFragmentViewModel.getTotalExpenseValue().observe(getViewLifecycleOwner(), new Observer<Double>() {
@Override
public void onChanged(Double aDouble) {
expenseTextView.setText(String.valueOf(aDouble));
mExpense += aDouble;
balanceTextView.setText(String.valueOf(mIncome - mExpense));
}
});
totalFragmentViewModel.getTotalIncomeValue().observe(getViewLifecycleOwner(), new Observer<Double>() {
@Override
public void onChanged(Double aDouble) {
incomeTextView.setText(String.valueOf(aDouble));
mIncome += aDouble;
balanceTextView.setText(String.valueOf(mIncome - mExpense));
}
});
回答1:
You can use MediatorLiveData
to aggregate multiple sources. In your case it will be aggregation of change events (data will be ignored), e.g, your view model might be implemented like this:
class MyViewModel extends ViewModel {
private MutableLiveData<Double> expense = new MutableLiveData<>();
private MutableLiveData<Double> income = new MutableLiveData<>();
private MediatorLiveData<Double> balance = new MediatorLiveData<>();
public MyViewModel() {
// observe changes of expense and income
balance.addSource(expense, this::onChanged);
balance.addSource(income, this::onChanged);
}
@AnyThread
public void updateExpense(Double value) {
expense.postValue(value);
}
@AnyThread
public void updateIncome(Double value) {
income.postValue(value);
}
// expose balance as LiveData if you want only observe it
public LiveData<Double> getBalance() {
return balance;
}
// argument is ignored because we don't know expense it or it is income
private void onChanged(@SuppressWarnings("unused") Double ignored) {
Double in = income.getValue(), ex = expense.getValue();
// correct value or throw exception if appropriate
if (in == null)
in = 0.0;
if (ex == null)
ex = 0.0;
// observer works on the main thread, we can use setValue() method
// => avoid heavy calculations
balance.setValue(in - ex);
}
}
回答2:
Try this:
totalFragmentViewModel.getTotalExpenseValue().observe(getViewLifecycleOwner(), new Observer<Double>() {
@Override
public void onChanged(Double expense) {
expenseTextView.setText(String.valueOf(expense));
mExpense += expense;
totalFragmentViewModel.getTotalIncomeValue().observe(getViewLifecycleOwner(), new Observer<Double>() {
@Override
public void onChanged(Double income) {
incomeTextView.setText(String.valueOf(income));
mIncome += income;
balanceTextView.setText(String.valueOf(mIncome - mExpense));
}
});
}
});
来源:https://stackoverflow.com/questions/55238222/livedata-mathematical-operations