0

ViewModel 的一个承诺是,它可以在屏幕旋转等情况下幸存下来。我仍然试图弄清楚如何在实践中组织它。

在模型的某些事件上,视图应该更新。有两个主要选项:

  1. ViewModel 更新视图。
  2. View 观察 ViewModel 并自行更新。

在第一种情况下,ViewModel 需要一个指向 View 的链接。我可以将 View 注入到 ViewModel 中,但我的感觉是将 VieModel 注入到 View 中会更好。

加入他们的更好的风格是什么?

然后在旋转之后再次调用 onCreate() 方法,再次触发 ViewModel 的初始化。我需要检查这一点,否则我有危险将听众注册到实际模型两次和三次以及类似问题。我什至可能需要先清理与旧视图的关系。

这种检查感觉有点不干净。如果这是一种标准做法,我希望在 ViewModel 中有一个专用的 API。没有我有走错路的感觉。

以干净的标准方式处理这个问题的好模式是什么?

4

1 回答 1

2

Soo .. 您实际上不必“关于屏幕旋转”连接 ViewModel 和 Activity/Fragment,您可以免费获得它——这是好处之一。

官方文档真的很好。

您可以通过以下方式将 ViewModel 连接到您的onCreate()视图

public class MyActivity extends AppCompatActivity {

    public void onCreate(Bundle savedInstanceState) {
        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            updateUI()
        });
    }
}

虽然您说方向更改将onCreate()再次触发是正确的,但这并不是真的会创建一个新的 ViewModel。MyViewModel仅在onCreate. 重新创建的活动接收MyViewModel由第一个活动创建的相同实例。这对于引用相同 ViewModel 的不同片段/活动来说也是如此。

您永远不应该将视图注入 ViewModel。这相当于溺水的小狗。如果您需要 ViewModel 中的上下文,请AndroidViewModel改为扩展(并将其传递给Application)。

您所做的是创建一个包含所有状态的 ViewModel。并处理从网络或磁盘或其他什么获取数据。所有与 UI 无关的内容都进入 ViewModel(根据经验)。所有视图更新内容都进入活动/片段。

上面示例的 ViewModel 可能看起来像

public class MyViewModel extends ViewModel {

    private MutableLiveData<List<User>> users;

    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<Users>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}

这通常意味着点击事件可能应该被传递到 ViewModel 以便它可以处理数据。视图只会对更新的(按摩的)数据做出反应。

于 2018-03-26T19:32:52.717 回答