首页 > 解决方案 > 实时数据数学运算

问题描述

我有两个实时数据。我需要对它们进行减法,但是如何用两个 livedata 来做呢?

我已经创建了类似的东西,但这不是正确的方法,因为它不会在我需要时总是刷新结果。

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

标签: android-livedata

解决方案


您可以使用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);
    }
}

推荐阅读