6

在 android 架构组件发布之前,我开始从事一个项目,我拥有自己的 ViewModel,它与 Fragment 具有相同的生命周期,并且 ViewModel 状态保存在 Loader 内的 StateObject 中,以便状态可以在方向变化后继续存在。ViewModel 通过接口与 Fragment 通信。这很好用,因为 ViewModel 和 Fragment 具有相同的生命周期。我的 ViewModel 包含各种状态。它有一个 isLoading 布尔值、isEmptyStateVisible 布尔值等。每次状态发生变化时,我都会调用 view.notifyIsLoadingChanged(true/false) 之类的东西,在这种情况下,Fragment 会显示或隐藏一个微调器。

现在我将更改我的实现以将新的 ViewModel 与 LiveData 一起使用。实现 LiveData 的最快方法是更改​​ ViewModel 正在使用的 UI 界面的实现。所以我可以保留我当前的实现,只添加这个 UI 接口实现:

public class LiveDataProductReviewSheetUI extends LiveDataUI implements ProductReviewSheetUI {
    public final MutableLiveData<ReviewViewModelState> ratingDescChanged = new MutableLiveData<>();
    public final MutableLiveData<ReviewViewModelState> ratingChanged = new MutableLiveData<>();
    public final MutableLiveData<ReviewViewModelState> reviewChanged = new MutableLiveData<>();
    public final MutableLiveData<ReviewViewModelState> reviewValid = new MutableLiveData<>();
    public final MutableLiveData<ReviewViewModelState> expandReview = new MutableLiveData<>();
    public final MutableLiveData<ReviewViewModelState> reviewQuestion = new MutableLiveData<>();
    public final MutableLiveData<ReviewViewModelState> reviewCreated = new MutableLiveData<>();
    public final MutableLiveData<ReviewViewModelState> showMsg = new MutableLiveData<>();
    public final MutableLiveData<ReviewViewModelState> dismiss = new MutableLiveData<>();

    public void observe(LifecycleOwner owner, final ProductReviewSheetUI observer) {
        ratingDescChanged.observe(owner, state -> observer.onRatingDescriptionChanged(state));
        ratingChanged.observe(owner, state -> observer.onRatingChanged(state));
        reviewChanged.observe(owner, state -> observer.onReviewChanged(state));
        reviewValid.observe(owner, state -> observer.onHasValidReviewDataChanged(state));
        expandReview.observe(owner, state -> observer.onExpandReviewFieldHasChanged(state));
        reviewQuestion.observe(owner, state -> observer.onProductReviewQuestionChanged(state));
        reviewCreated.observe(owner, state -> observer.onReviewCreated(state));
        showMsg.observe(owner, state -> observer.onShowMessage(state));
        dismiss.observe(owner, state -> observer.onCloseView());
    }

    @Override
    public void onRatingDescriptionChanged(ReviewViewModelState state) {
        ratingDescChanged.setValue(state);
    }

    @Override
    public void onRatingChanged(ReviewViewModelState state) {
        ratingChanged.setValue(state);
    }

    @Override
    public void onReviewChanged(ReviewViewModelState state) {
        reviewChanged.setValue(state);
    }

    @Override
    public void onHasValidReviewDataChanged(ReviewViewModelState state) {
        reviewValid.setValue(state);
    }

    @Override
    public void onExpandReviewFieldHasChanged(ReviewViewModelState state) {
        expandReview.setValue(state);
    }

    @Override
    public void onProductReviewQuestionChanged(ReviewViewModelState state) {
        reviewQuestion.setValue(state);
    }

    @Override
    public void onReviewCreated(ReviewViewModelState state) {
        reviewCreated.setValue(state);
    }

    @Override
    public void onShowMessage(ReviewViewModelState state) {
        showMsg.setValue(state);
    }

    @Override
    public void onCloseView() {
        dismiss.setValue(dismiss.getValue());
    }
}

此类扩展的 LiveDataUI 类具有更多方法,例如:

public final MutableLiveData<Boolean> showLoading = new MutableLiveData<>();
public final MutableLiveData<Boolean> showEmptyState = new MutableLiveData<>();

有了这个实现,我最终会得到很多 MutableLiveData 对象,而且感觉不对。我是否在我的 ViewModel 中投入了太多的状态?我的想法是将所有逻辑都包含在 ViewModel 中,这样我就可以编写测试来验证在加载数据时 isLoading 是否为真,如果 Api 没有返回数据,则 isEmptyState 为真等。

我还注意到,如果我调用 setValue(state); 在同一个 MutableLiveData 对象上很短的时间内多次,onChanged 方法只被调用一次。那是对的吗?

4

0 回答 0