问题描述
当前,我致力于RecycleView的自定义多视图类型.我找到了解决此问题的许多解决方案,但我会分享我的方式.
Currently, I work on custom multi-view types for RecycleView.I found many solutions for this problem, but I will share my way.
不同之处在于,使用enum
定义ViewType.
The different is use enum
for define ViewType.
请参阅我的答案以获取更多详细信息.(只想分享).
See my answer for more detail.(Just want to share).
推荐答案
更新
我建议阅读这篇文章:编写更好的适配器
I recommend read this article: Writing Better Adapter
这是我为RecyclewView自定义多视图类型的方式.
Here is the way I custom multi-view types for RecyclewView.
我将首先显示代码,然后在下面解释.
I will show the code first, then explain bellow.
@SuppressWarnings("unchecked")
public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
private final List<Wrapper<?>> items;
public BaseAdapter() {
this.items = new ArrayList<>();
}
@Override
public int getItemViewType(int position) {
return items.get(position).viewType;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return ViewType.values()[viewType].onCreateViewHolder(parent);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.onBind(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
public void simulateAddItems() {
items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
items.add(new Wrapper<>(ViewType.BOTTOM.viewTYpe(), new BottomData()));
notifyDataSetChanged();
}
public enum ViewType {
USER {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
return new UserViewHolder(itemView);
}
},
BOTTOM {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
return new BottomViewHolder(itemView);
}
};
public abstract ViewHolder onCreateViewHolder(ViewGroup parent);
public int viewTYpe() {
return ordinal();
}
}
static class Wrapper<T> {
final int viewType;
final T data;
public Wrapper(int viewType, T data) {
this.viewType = viewType;
this.data = data;
}
}
public static class ViewHolder<T> extends RecyclerView.ViewHolder {
private T item;
public ViewHolder(View itemView) {
super(itemView);
}
public void onBind(T item) {
}
}
public static class UserViewHolder extends ViewHolder<User> {
public UserViewHolder(View itemView) {
super(itemView);
}
@Override
public void onBind(User item) {
super.onBind(item);
}
}
public static class BottomViewHolder extends ViewHolder<BottomData> {
public BottomViewHolder(View itemView) {
super(itemView);
}
@Override
public void onBind(BottomData item) {
super.onBind(item);
}
}
static class User {
// user fields & method
}
static class BottomData {
// bottom data fields & method
}
}
您可以看到适配器具有一些特殊之处:
You can see the adapter have something special:
-
Adapter的数据是通用&从
Wrapper
类扩展.Wrapper
类只是POJO类,包含两个字段viewType
&item
数据.viewType
将通过getItemViewType(int position)
传递,而item
是每个视图持有者的数据.
The data of Adapter is generic & extends from
Wrapper
class. TheWrapper
class simply POJO class contain two fieldsviewType
&item
data. TheviewType
will be passing viagetItemViewType(int position)
and theitem
is data for each view holder.
带有T
的通用ViewHolder
是视图持有者的一种数据.您可以看到两个自定义视图保存器UserViewHolder
和BottomViewHolder
从ViewHolder
扩展到此数据. (因此,每个视图持有人的onBind
中将拥有他们想要使用的确切数据->无需强制转换.因为我们已经在强制转换中了.)
The generic ViewHolder
with T
is kind of data for the view holder. You can see two custom view holder UserViewHolder
and BottomViewHolder
extends from ViewHolder
with this data. (So in onBind
of each view holder will have exact data they want to use -> no need to cast. Because we already in cast).
枚举ViewType
包含适配器的所有视图类型.另外,在视图类型中,我们有方法ViewHolder onCreateViewHolder(ViewGroup parent)
,因此我们可以更容易地从ViewType
制作viewHolder.我认为相对于ViewType,我们的眼睛更容易看到Holder.
The enum ViewType
contain all view type of adapter. Also, in view type, we have method ViewHolder onCreateViewHolder(ViewGroup parent)
so we can easier make viewHolder from ViewType
. I think it is easier for our eyes to see the Holder relative to the ViewType.
此外,我们有方法viewType()
,它只返回枚举的ordinal()
.作为java docs
中的参考,该方法可能不使用.但是在这种情况下,我认为使用起来很公平(因为它是唯一的).
Also, we have method viewType()
it simply return ordinal()
of enum.As a reference in java docs
that method may not use. But in this case, I think it is fair enough to use (because it is unique).
因此,在Adapter的方法onCreateViewHolder
中,我们可以简单地调用:return ViewType.values()[viewType].onCreateViewHolder(parent);
So in the method onCreateViewHolder
of Adapter we can simple call:return ViewType.values()[viewType].onCreateViewHolder(parent);
,在onBindViewHolder
中,我们将调用holder.onBind(items.get(position));
.
and in onBindViewHolder
we will call holder.onBind(items.get(position));
.
最后,我制作了simulateAddItems
演示如何将项目添加到适配器.
Finally, I made simulateAddItems
for demo how we add item to the adapter.
使用RecycleView的自定义视图类型时,这里有一些经验.我希望它有用&帮助别人.
Here is some experiences while working with custom view type for RecycleView. I hope it useful & help other people.
这篇关于如何实现RecycleView的多种视图类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!