Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在处理RecyclerView列表项时使用继承是一种反模式吗?_Java_Android_Android Recyclerview - Fatal编程技术网

Java 在处理RecyclerView列表项时使用继承是一种反模式吗?

Java 在处理RecyclerView列表项时使用继承是一种反模式吗?,java,android,android-recyclerview,Java,Android,Android Recyclerview,我有两个类,我想混合和匹配成一个回收视图,ItemA和ItemB。为了做到这一点,我给了他们一个基类BaseItem,这样他们就可以作为一个列表传入。然后在我的RecyclerAdapter的getItemViewType方法中,我计算出类是什么,以便使用正确的Viewholder 在这一点上,我内心的反模式本能开始爆发。我通常认为,如果必须计算出处理对象的具体类是什么,那么它就不应该有基类。这样做是错误的吗?我找不到任何类似的例子 有好的替代方案吗? 我编写了一些代码来说明我的观点 publi

我有两个类,我想混合和匹配成一个回收视图,ItemA和ItemB。为了做到这一点,我给了他们一个基类BaseItem,这样他们就可以作为一个列表传入。然后在我的RecyclerAdapter的getItemViewType方法中,我计算出类是什么,以便使用正确的Viewholder

在这一点上,我内心的反模式本能开始爆发。我通常认为,如果必须计算出处理对象的具体类是什么,那么它就不应该有基类。这样做是错误的吗?我找不到任何类似的例子

有好的替代方案吗? 我编写了一些代码来说明我的观点

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替换原则