Livedata математические операции - PullRequest
0 голосов
/ 19 марта 2019

У меня есть две жизни. Мне нужно взять на них вычитание, но как это сделать с двумя ливатами?

Я создал что-то подобное, но это неправильный способ, потому что он не обновляет результат всегда, когда мне это нужно.

       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));
        }
    });

Ответы [ 2 ]

2 голосов
/ 25 марта 2019

Вы можете использовать MediatorLiveData для объединения нескольких источников. В вашем случае это будет агрегация событий изменения (данные будут игнорироваться), например, ваша модель представления может быть реализована следующим образом:

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);
    }
}
1 голос
/ 20 марта 2019

Попробуйте это:

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));
        }
    });
    }
});
...