在 RecycleView 适配器中实现多种 ViewHolder 类型 [英] Implement multiple ViewHolder types in RecycleView adapter
问题描述
这可能是讨论而不是问题.
实现多种类型的正常方式
如你所知,如果我们想在RecyclerView
中实现多种类型,我们应该提供多个CustomViewHolder
扩展RecyclerView.ViewHolder
.
例如,
class TextViewHolder 扩展 RecyclerView.ViewHolder{文本视图文本视图;}类 ImageViewHolder 扩展 RecyclerView.ViewHolder{图像视图图像视图;}
然后我们必须重写getItemViewType
.并且在onCreateViewHolder
中构造TextViewHolder
或ImageViewHolder
.
@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {如果(视图类型 == 0){返回新的 ImageViewHolder(mLayoutInflater.inflate(R.layout.item_image, parent, false));} 别的 {返回新的 TextViewHolder(mLayoutInflater.inflate(R.layout.item_text, parent, false));}}
上面的代码是正常的,但还有另一种方式.
另一种方式
我认为只有一个 CustomViewHolder
就足够了.
class MultipleViewHolder 扩展 RecyclerView.ViewHolder{文本视图文本视图;图像视图图像视图;MultipleViewHolder(查看 itemView,int 类型){如果(类型== 0){textView = (TextView)itemView.findViewById(xx);}别的{imageView = (ImageView)itemView.findViewById(xx);}}}
您在开发工作中使用哪种方式?
我个人喜欢 Yigit Boyar 建议的方法在 本次演讲(快进到 31:07).不是从 getItemViewType()
返回一个 constant int,而是直接返回布局 id,它也是一个 int 并且保证是唯一的:
这将允许您在 onCreateViewHolder()
中有以下实现:
其中 MyViewHolder
是一个抽象类:
和 FirstViewHolder
如下:
这将使 onBindViewHolder()
成为单行:
因此,您将每个 ViewHolder
分开,其中 bind(Item)
将负责执行特定于该 ViewHolder
的操作.
It's maybe a discussion not a question.
Normal way to implement multiple types
As you know, if we want to implement multiple types in RecyclerView
, we should provide multiple CustomViewHolder
extending RecyclerView.ViewHolder
.
For exmpale,
class TextViewHolder extends RecyclerView.ViewHolder{
TextView textView;
}
class ImageViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
}
Then we have to override getItemViewType
.And in onCreateViewHolder
to construct TextViewHolder
or ImageViewHolder
.
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 0) {
return new ImageViewHolder(mLayoutInflater.inflate(R.layout.item_image, parent, false));
} else {
return new TextViewHolder(mLayoutInflater.inflate(R.layout.item_text, parent, false));
}
}
Above code is normal but there is a another way.
Another way
I think only one CustomViewHolder
is enough.
class MultipleViewHolder extends RecyclerView.ViewHolder{
TextView textView;
ImageView imageView;
MultipleViewHolder(View itemView, int type){
if(type == 0){
textView = (TextView)itemView.findViewById(xx);
}else{
imageView = (ImageView)itemView.findViewById(xx);
}
}
}
Which way do you use in your developing work?
Personally I like approach suggested by Yigit Boyar in this talk (fast forward to 31:07). Instead of returning a constant int from getItemViewType()
, return the layout id directly, which is also an int and is guaranteed to be unique:
@Override
public int getItemViewType(int position) {
switch (position) {
case 0:
return R.layout.first;
case 1:
return R.layout.second;
default:
return R.layout.third;
}
}
This will allow you to have following implementation in onCreateViewHolder()
:
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(viewType, parent, false);
MyViewHolder holder = null;
switch (viewType) {
case R.layout.first:
holder = new FirstViewHolder(view);
break;
case R.layout.second:
holder = new SecondViewHolder(view);
break;
case R.layout.third:
holder = new ThirdViewHolder(view);
break;
}
return holder;
}
Where MyViewHolder
is an abstract class:
public static abstract class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView) {
super(itemView);
// perform action specific to all viewholders, e.g.
// ButterKnife.bind(this, itemView);
}
abstract void bind(Item item);
}
And FirstViewHolder
is following:
public static class FirstViewHolder extends MyViewHolder {
@BindView
TextView title;
public FirstViewHolder(View itemView) {
super(itemView);
}
@Override
void bind(Item item) {
title.setText(item.getTitle());
}
}
This will make onBindViewHolder()
to be one-liner:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.bind(dataList.get(holder.getAdapterPosition()));
}
Thus, you'd have each ViewHolder
separated, where bind(Item)
would be responsible to perform actions specific to that ViewHolder
only.
这篇关于在 RecycleView 适配器中实现多种 ViewHolder 类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!