Java 在处理RecyclerView列表项时使用继承是一种反模式吗?
我有两个类,我想混合和匹配成一个回收视图,ItemA和ItemB。为了做到这一点,我给了他们一个基类BaseItem,这样他们就可以作为一个列表传入。然后在我的RecyclerAdapter的getItemViewType方法中,我计算出类是什么,以便使用正确的Viewholder 在这一点上,我内心的反模式本能开始爆发。我通常认为,如果必须计算出处理对象的具体类是什么,那么它就不应该有基类。这样做是错误的吗?我找不到任何类似的例子 有好的替代方案吗? 我编写了一些代码来说明我的观点Java 在处理RecyclerView列表项时使用继承是一种反模式吗?,java,android,android-recyclerview,Java,Android,Android Recyclerview,我有两个类,我想混合和匹配成一个回收视图,ItemA和ItemB。为了做到这一点,我给了他们一个基类BaseItem,这样他们就可以作为一个列表传入。然后在我的RecyclerAdapter的getItemViewType方法中,我计算出类是什么,以便使用正确的Viewholder 在这一点上,我内心的反模式本能开始爆发。我通常认为,如果必须计算出处理对象的具体类是什么,那么它就不应该有基类。这样做是错误的吗?我找不到任何类似的例子 有好的替代方案吗? 我编写了一些代码来说明我的观点 publi
public class ItemRecyclerAdapter extends RecyclerView.Adapter<BaseViewHolder> {
private FragmentManager fragmentManager;
private static final int TYPE_A = 0;
private static final int TYPE_B = 1;
private final LayoutInflater inflater;
private List<BaseItem> items;
public ItemRecyclerAdapter(Context context, List<BaseItem> items, FragmentManager fragmentManager) {
this.fragmentManager = fragmentManager;
inflater = LayoutInflater.from(context);
this.items = items;
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_A:
ViewGroup v = // Get viewGroup
ViewHolderA viewHolderA = new ViewHolderA(v);
return viewHolderA;
default:
ViewGroup defaultViewGroup = // Get viewGroup
ViewHolderB viewHolderB = new ViewHolderB(defaultViewGroup);
return viewHolderB;
}
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
BaseMenuItem item = items.get(position);
switch (holder.getItemViewType()) {
case TYPE_A:
ViewHolderA va = (ViewHolderA) holder;
ViewHolderA.setData((ItemA) item);
break;
case TYPE_B:
ViewHolderB vb = (ViewHolderB) holder;
ViewHolderB.setData((ItemB) item);
break;
}
}
@Override
public int getItemViewType(int position) {
BaseMenuItem item = items.get(position);
boolean IsItemTypeA = item.getClass() == ItemA.class;
if (IsItemTypeA) {
return TYPE_A;
}
return TYPE_B;
}
@Override
public int getItemCount() {
if (items == null) {
return 0;
}
return items.size();
}
public abstract class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(View itemView) {
super(itemView);
}
}
private class ViewHolderA extends BaseViewHolder {
// ViewHolder stuff here.
}
private class ViewHolderB extends BaseViewHolder {
// ViewHolder stuff here.
}
}
公共类ItemRecyclerAdapter扩展了RecyclerView.Adapter{
私人碎片管理器碎片管理器;
私有静态最终整数类型_A=0;
私有静态最终整数类型_B=1;
私人充气机;
私人清单项目;
公共项回收器适配器(上下文上下文、列表项、碎片管理器碎片管理器){
this.fragmentManager=fragmentManager;
充气器=充气器。从(上下文);
这个项目=项目;
}
@凌驾
public BaseViewHolder onCreateViewHolder(视图组父级,int-viewType){
开关(视图类型){
案例类型_A:
ViewGroup v=//获取ViewGroup
ViewHolderA ViewHolderA=新ViewHolderA(v);
返回viewHolderA;
违约:
ViewGroup defaultViewGroup=//获取视图组
ViewHolderB ViewHolderB=新ViewHolderB(默认视图组);
返回viewHolderB;
}
}
@凌驾
BindViewHolder上的公共无效(BaseViewHolder,int位置){
BaseMenuItem item=items.get(位置);
开关(holder.getItemViewType()){
案例类型_A:
ViewHolderA va=(ViewHolderA)支架;
ViewHolderA.setData((ItemA)项);
打破
案例类型_B:
ViewHolderB vb=(ViewHolderB)支架;
ViewHolderB.setData((ItemB)项);
打破
}
}
@凌驾
public int getItemViewType(int位置){
BaseMenuItem item=items.get(位置);
布尔值IsItemTypeA=item.getClass()==ItemA.class;
如果(IsItemTypeA){
返回类型_A;
}
返回类型_B;
}
@凌驾
public int getItemCount(){
if(items==null){
返回0;
}
返回items.size();
}
公共抽象类BaseViewHolder扩展了RecyclerView.ViewHolder{
公共BaseViewHolder(视图项视图){
超级(项目视图);
}
}
私有类ViewHolderA扩展了BaseViewHolder{
//这里有视窗支架。
}
私有类ViewHolder B扩展了BaseViewHolder{
//这里有视窗支架。
}
}
我个人不认为这是反模式。对于这些场景,我实现了一个名为委托适配器的模式,这是对文章思想的修改(推荐讲座)
我建议您对当前的实现进行一些修改:
- 在
BaseItem
中指定一个声明其视图类型的抽象方法,并让它的子级实现所述方法。类似于getViewType
这样可以避免讨厌的getClass
比较
- 将注册的视图类型存储在实用程序类中,或者更好地存储在IntDef定义中,以获得更清晰的代码
M个人观点是,如果这两个模型没有逻辑关系,因此不共享任何公共属性,或者不能用抽象表示,那么这将被视为反模式
如果您的唯一目标是只传入一个包含两个模型的列表,请传入一个列表
查看liskov替换原则