Android:以正确的方式应用 MVVM(第三部分)

Android: Applying MVVM the correct way (Part III)

为了使我的 mvvm 迁移达到最佳效果,我从社区获得了宝贵的帮助,但仍然对一些问题有疑问,例如:

我已将下一个方法从 activity 移至 ViewModel(因为它主要是业务),但不确定它是否完全正确,因为它处理视图。其中一个参数是一个以编程方式创建的 ImageView,我会说即使它是以编程方式创建的,它仍然是一个视图,并且当 VM 不被支持时,我间接将上下文传递给 VM(并直接传递一个视图元素)处理视图。

简而言之,我不确定 - 是 mvvm strict - 是否可以接受将此方法(或处理以编程方式创建的视图的任何方法)移动到 VM。

public void setCheckBoxCheckedState_TestMode(List<AnswerDTO> answers,
                 int pageNumber, int cbSelectedId, ImageView cbAnswer)
{
    for (int j = 0; j < answers.size(); j++) {
        int cbIndex = answers.size() * pageNumber + j;
        if (cbIndex != cbSelectedId) {
            setCheckBoxUnchecked_TestMode(cbIndex);
            String strRest = cbAnswer.getTag().toString().substring(1);
            cbAnswer.setTag("0" + strRest);
        } else {
            String cbAnswerJTag = cbAnswer.getTag().toString();
            String cbAnswerJState = cbAnswerJTag.split("@")[0];

            if (cbAnswerJState.equals("1")) { // 0=>unchecked|1=>checked
                setCheckBoxUnchecked_TestMode(cbIndex);
                cbAnswer.setTag("0@" + cbAnswerJTag.split("@")[1]);
            } else {
                setCheckBoxChecked_TestMode(cbIndex);
                cbAnswer.setTag("1@" + cbAnswerJTag.split("@")[1]);
            }
        }
    }
}

首先,任何时候您以编程方式创建 Views,您都可能走错了路。您可能希望 RecyclerView 为您执行此操作。另一个巨大的危险信号是您正在使用 getTag()ImageView 中存储信息。无论这些信息是什么,它都应该存储在列表或其他一些数据结构中(可能只是在您已经拥有的 List<AnswerDTO> 中)。

基本上,当您应该首先学习更多核心 Android 概念时,您正在尝试实施 MVVM。以 class 开头,例如 this one.

实际上,您应该告诉视图模型什么事件发生了变化(例如 viewModel.onSelectionChange(itemDataId)),然后视图模型应该知道它需要更改哪些“数据”以更新视图模型的内部状态, 这应该被视图观察到,通常与数据绑定。

目前您正在为视图模型提供“视图”相关对象 - ImageView - 它不应直接在视图对象上设置状态,即基于视图模型状态的视图关注点。看起来您只是将视图函数移动到视图模型,但它不属于那里。

像这样:

视图 <-- 数据绑定 --> 视图模型 <------> 模型

或没有数据绑定:

视图 -- 事件 ---> ViewModel <------> 模型

视图<----数据更新---视图模型<------>模型