我可以将ViewModel传递给RecyclerView适配器并观察LiveData吗?

时间:2018-07-15 08:23:27

标签: android mvvm data-binding recycler-adapter

我开始实现MVVM,但我不知道在ViewModel中使用Adapter是好的做法还是反模式。

举个例子,考虑一下颜色列表和一个将改变背景的图像。在这种情况下,我将观察所选的颜色,并将背景颜色绑定到要在UI中显示。

但是我在两个地方观察到了colorSelected:

  • Fragment中以更改背景颜色
  • Adapter中显示选择的颜色

那么,当我将MVVM传递并观察到ViewModel时,我是否正确使用Adapter

2 个答案:

答案 0 :(得分:1)

我现在不确定这是否是好的模式,但这有一个问题: 这样,您的适配器便会与ViewModel绑定在一起,这意味着您无法在其他屏幕上将其与其他ViewModel一起使用。另一方面,如果没有来自recyclerView的其他回调,则工作起来会容易得多,这使实现更加容易。我想使用回调“更好”,但通过ViewModel“更轻松”(我认为CG应该可以毫无问题地处理它)

答案 1 :(得分:1)

嗯,这个问题我找了解决办法,最后还是得自己处理。我想在这里发表我的想法以供讨论。

简单地说,在我看来,将 viewModel 实例传递给适配器并不优雅。相反,我建议您覆盖 RecyclerViewAdapter 的“onAttachedToRecyclerView”方法来获取您的 viewModel

public class YoursAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
......
private YoursViewModel viewModel;
......
    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        if(viewModel==null){
            viewModel=new ViewModelProvider((ViewModelStoreOwner) recyclerView.getContext()).get(YoursViewModel.class);
        }
    }
......
}

为什么我认为这个解决方案很好?

1、ViewModel 本身与上下文无关。但是创建 ViewModel 的实例需要一个上下文。

2、您选择哪种语境? recyclerView 的上下文,因为你想在适配器内部做一些事情,而适配器与一个 recyclerView 相关联。为什么我覆盖了“onAttachedToRecyclerView”?因为这个回调提供了一个 recyclerView 引用,并且只执行一次。

3、只要recyclerView的上下文还活着,ViewModel就活着。是你想要的吗?如果答案是“是”,那么根据 recyclerView 的上下文创建您的 ViewModel 实例是合理的。

4、你在Fragment中有一个ViewModel。在适配器中创建一个新的是否合理?是的。 One of the advantages of ViewModel is sharing data只要他们在同一个活动中

5、如果您正确设计了ViewModel,您实际上不需要观察适配器内部的实时数据(再次需要上下文)。基本上你只是观察片段上的实时数据。适配器内的 ViewModel 只负责更改数据,而不关心数据如何更改,即在片段上执行 yourViewModelInstance.post_value_to_liveData_and return_it().observe(),并在适配器内执行 yourViewModelInstance.post_value_to_liveData_and return_it()