[英]Is it an anti-pattern to use inheritance when handling RecyclerView list items?
I have two classes I want to mix and match into a recyclerView, ItemA and ItemB.我有两个类我想混合和匹配到一个 recyclerView,ItemA 和 ItemB。 In order to do this I've given them a base class of BaseItem so they can be passed in as one List.
为了做到这一点,我给了他们一个 BaseItem 的基类,这样他们就可以作为一个 List 传入。 Then in my RecyclerAdapter's getItemViewType method I work out what the class is so I can use the correct Viewholder.
然后在我的 RecyclerAdapter 的 getItemViewType 方法中,我计算出类是什么,以便我可以使用正确的 Viewholder。
At this point my internal anti-pattern instincts started flaring up.在这一点上,我内心的反模式本能开始燃烧起来。 I generally feel that if you have to work out what the concrete class is to handle an object then it shouldn't have a base class.
我通常认为,如果您必须弄清楚处理对象的具体类是什么,那么它就不应该有基类。 Is this the wrong way to go about doing this?
这是错误的做法吗? I've been unable to find any examples of people doing similarly.
我一直无法找到任何类似的人的例子。
Is there a good alternative to this?有什么好的替代方法吗? I put together some code to illustrate my point.
我整理了一些代码来说明我的观点。
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.
}
}
I personally do not consider it an anti pattern.我个人不认为这是一种反模式。 For those scenarios Ive implemented a pattern called delegate adapter which is a modification from an idea of this article (lecture recommended).
对于这些场景,我实现了一种称为委托适配器的模式,这是对本文思想的修改(推荐讲座)。
I do recommend though some modifications to your current implementation:我确实建议对您当前的实现进行一些修改:
BaseItem
that declares its view type, and let it children implement said method.BaseItem
中指定一个声明其视图类型的抽象方法,并让它子项实现该方法。 Something like getViewType
that way you avoid the nasty getClass
comparison.getViewType
这样的东西,你可以避免讨厌的getClass
比较。M personal opinion, is that it would be considered an anti-pattern if those two models have no logical relationship, hence not sharing any common attributes, or cannot be expressed with an abstraction.我个人的看法是,如果这两个模型没有逻辑关系,因此没有共享任何共同属性,或者不能用抽象来表达,那么它会被认为是反模式。
If your only goal is to only pass in a list containing both models, pass a List<Object>
如果您的唯一目标是只传入包含两个模型的
List<Object>
,请传递List<Object>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.