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

标签 java android android-recyclerview

我有两个类要混合并匹配到 recyclerView,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.
    }
}

最佳答案

我个人不认为它是反模式。对于这些场景,我实现了一种称为委托(delegate)适配器的模式,它是对 this 想法的修改。文章(推荐讲座)。

我确实建议对您当前的实现进行一些修改:

  • BaseItem 中指定一个声明其 View 类型的抽象方法,并让其子级实现该方法。像 getViewType 这样的东西可以避免讨厌的 getClass 比较。
  • 将您注册的 View 类型存储在实用程序类中,或者更好地存储在 IntDef 定义中以获得更清晰的代码。

关于java - 在处理 RecyclerView 列表项时使用继承是一种反模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47457326/

相关文章:

java - 如何使用 GMaps API 将 KML 文件导入 Android 应用程序

java - 有没有一种检查 Datastax Session.executeAsync() 是否抛出异常的好方法?

java - java中的随机标识符

android - 如何在设备管理员停用时删除 Android 设备?

java - 如何更新 recyclerview 项目中的上传进度百分比?

android - AsyncTask RecyclerView NullPointerException

java - Controller 组件在哪里?

android - 如何在 Android 中使用 GPUImage 在视频上添加滤镜?

java - 如何转换特殊字符, "Fran%c3%a7ais"-> "Français"?

android - 保存我的 recyclerview 和 cardview 的状态