Android架构组件:对RecyclerView项使用ViewModel

Android架构组件:对RecyclerView项使用ViewModel,android,mvvm,android-recyclerview,android-architecture-components,Android,Mvvm,Android Recyclerview,Android Architecture Components,我正在试验体系结构组件,我想为RecyclerView的每个项目构建一个ViewModel。我不确定这在形式上是否正确,或者我应该坚持“老办法” 我有这个适配器: 公共类PostAdapter扩展了RecyclerView.Adapter{ 私人名单; 公共静态类PostViewHolder扩展了RecyclerView.ViewHolder{ 最终条款后绑定; 公共PostViewHolder(ItemPostBinding绑定){ super(binding.getRoot()); 这个。绑

我正在试验体系结构组件,我想为RecyclerView的每个项目构建一个ViewModel。我不确定这在形式上是否正确,或者我应该坚持“老办法”

我有这个适配器:

公共类PostAdapter扩展了RecyclerView.Adapter{
私人名单;
公共静态类PostViewHolder扩展了RecyclerView.ViewHolder{
最终条款后绑定;
公共PostViewHolder(ItemPostBinding绑定){
super(binding.getRoot());
这个。绑定=绑定;
}
}
@凌驾
public PostViewHolder onCreateViewHolder(视图组父级,int-viewType){
ItemPostBinding=DataBindingUtil
.充气(LayoutInflater.from(parent.getContext()),R.layout.item\u post,
父母,假);
返回新的PostViewHolder(绑定,parent.getContext());
}
@凌驾
公共无效onBindViewHolder(PostViewHolder,内部位置){
holder.binding.setPost(list.get(position));
holder.binding.executePendingBindings();
}
@凌驾
public int getItemCount(){
返回列表==null?0:list.size();
}
公共无效集合列表(列表){
this.list=列表;
notifyDataSetChanged();
}
}
这很好,但很基本。如何更新它,使每个项目都有自己的关联ViewModel?这可能吗

编辑:使用它,我尝试以以下方式放入ViewModels:

公共类PostAdapter扩展了RecyclerView.Adapter{
私人名单;
公共静态类PostViewHolder扩展了RecyclerView.ViewHolder{
最终条款后绑定;
私人最终语境;
私有GalleryItemViewModel视图模型;
公共PostViewHolder(ItemPostBinding绑定,上下文){
super(binding.getRoot());
这个。绑定=绑定;
this.context=上下文;
}
公共上下文getContext(){
返回上下文;
}
公共void setViewModel(GalleryItemViewModel viewModel){
this.viewModel=viewModel;
binding.setViewModel(viewModel);
}
}
@凌驾
public PostViewHolder onCreateViewHolder(视图组父级,int-viewType){
ItemPostBinding=DataBindingUtil
.充气(LayoutInflater.from(parent.getContext()),R.layout.item\u post,
父母,假);
返回新的PostViewHolder(绑定,parent.getContext());
}
@凌驾
公共无效onBindViewHolder(PostViewHolder,内部位置){
GalleryItemViewModel vm=ViewModelProviders.of((FragmentActivity)holder.getContext()).get(GalleryItemViewModel.class);
vm.setPost(list.get(position));
holder.setViewModel(vm);
}
@凌驾
public int getItemCount(){
返回列表==null?0:list.size();
}
公共无效集合列表(列表){
this.list=列表;
notifyDataSetChanged();
}
}

这是有效的,但这是正确的方法吗?

很有趣,但回答-这是正确的方法,应该被接受:) 您可以进行一些代码清理,并从
PostViewHolder
中删除
GalleryItemViewModel
,因为您正在创建硬引用而不使用它。 然后直接在
onBindViewHolder()
中像
holder.binding.setViewModel(vm)一样使用它


这是一个MVVM代码示例,可以帮助您。

首先,正确的ViewModel实现应该是扩展
android.arch.lifecycle.ViewModel
。扩展
BaseObservable
使ViewModel类成为数据类的示例,但它应该是表示类,因为它正在取代MVP模式的表示者

另一件事是
ViewModelProviders.of(context).get(Class.Class)
为每个调用返回相同的ViewModel,它允许您在视图之间共享相同的数据

此外,ViewModel类不应该,或者包含来自Android环境的最小类,并且不应该保留对视图类的任何引用,因为它可能比视图更有效

在第二个示例中,您可能使用

public void setViewModel(GalleryItemViewModel viewModel){
            this.viewModel = viewModel;
            binding.setViewModel(viewModel);
}
能否共享布局文件,以及如何使用ViewModel类实现此功能

对于MVVM和数据绑定,接受答案中的示例链接不是正确的示例

链接集中的ViewModel类,如第二个示例所示:

public class CommentHeaderViewModel extends BaseObservable {

    private Context context;
    private Post post;

    public CommentHeaderViewModel(Context context, Post post) {
        this.context = context;
        this.post = post;
    }

    public String getCommentText() {
        return Html.fromHtml(post.text.trim()).toString();
    }

    public String getCommentAuthor() {
        return context.getResources().getString(R.string.text_comment_author, post.by);
    }

    public String getCommentDate() {
        return new PrettyTime().format(new Date(post.time * 1000));
    }

}
这是一个数据类,而不是ViewModel类,它还导入视图类,这对单元测试不利


这是data binding+RecyclerView教程,正确的命名不应该是这个类的..ViewModel。用于数据类并将其与RecyclerView绑定。

确保在获取ViewModel时分配唯一标识符,因为在引擎盖下,ViewModelProviders将为您提供相同的实例,否则

获取(一些唯一id,GalleryItemViewModel.class)

因此,请尝试在此处添加id,如下所示:

 GalleryItemViewModel vm = ViewModelProviders.of((FragmentActivity) holder.getContext()).get(**some unique id**, GalleryItemViewModel.class);
    vm.setPost(list.get(position));
    holder.setViewModel(vm);

你好,Jacopo,你可以用不同的方式使用适配器。你能给我一个例子或一个链接吗?如果你觉得有问题,可以从下面的链接中查看答案,然后问我…
ViewModelProviders.of((FragmentActivity)holder.getContext()).get(GalleryItemViewModel.class)
在随后的调用中,该函数不会返回相同的
GalleryItemViewModel
对象吗?我想您应该使用
ViewModelProvider
的重载方法
get(@NonNull String key,@NonNull Class modelClass)
,并通过
onBindViewHolder
调用传递unique key来获取unique viewModel。我来看看!感谢nowViewModel类不应该有上下文引用。我写道不应该,请仔细阅读。此外,ViewModel类不应包含