【问题标题】:How can LiveData in ViewModel observe the Livedata in Repository using Transformations?ViewModel 中的 LiveData 如何使用 Transformations 观察 Repository 中的 Livedata?
【发布时间】:2017-12-26 06:09:30
【问题描述】:

我在我的存储库中使用了一个 AsyncTask,它用于在存储库中设置 LiveData。如何使用转换从我的 ViewModel 观察此 LiveData?

【问题讨论】:

    标签: android android-asynctask android-architecture-components android-livedata


    【解决方案1】:

    你可以忽略我的其他答案。解决方案是在您的视图模型中使用 MediatorLiveData。您将存储库中的 LiveData 作为数据源添加到 MediatorLiveData 并在观察者 onChanged 回调中调用 setValue 或 postValue(取决于它是否在 UI 中)。

    像这样

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

    【讨论】:

    • MediatorLiveData 本身需要有一个活跃的观察者
    【解决方案2】:

    所以我今天就在尝试这个东西,但无法让它发挥作用。我都试过了

    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 中的一个方法将 Transaction 返回给 view model

    public void transactionLoaded(Transaction transaction) {
        initialTransaction = new Transaction(transaction);
        currentTransaction.setValue(transaction);
    }
    

    然后我还将活动设置为也观察 currentTransaction 和 MutableLiveData

    更多的 sn-ps 希望能澄清我的所作所为。

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

    这并不理想,因为除非片段/活动参与但它确实起作用,否则它不会起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多