Android架构组件:对RecyclerView项使用ViewModel
我正在试验体系结构组件,我想为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()); 这个。绑
公共类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类不应包含