簡體   English   中英

在處理 RecyclerView 列表項時使用繼承是一種反模式嗎?

[英]Is it an anti-pattern to use inheritance when handling RecyclerView list items?

我有兩個類我想混合和匹配到一個 recyclerView,ItemA 和 ItemB。 為了做到這一點,我給了他們一個 BaseItem 的基類,這樣他們就可以作為一個 List 傳入。 然后在我的 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.
    }
}

我個人不認為這是一種反模式。 對於這些場景,我實現了一種稱為委托適配器的模式,這是對本文思想的修改(推薦講座)。

我確實建議對您當前的實現進行一些修改:

  • BaseItem中指定一個聲明其視圖類型的抽象方法,並讓它子項實現該方法。 getViewType這樣的東西,你可以避免討厭的getClass比較。
  • 將您注冊的視圖類型存儲在實用程序類中,或者甚至更好的 IntDef 定義中,以便更清晰的代碼。

我個人的看法是,如果這兩個模型沒有邏輯關系,因此沒有共享任何共同屬性,或者不能用抽象來表達,那么它會被認為是反模式。

如果您的唯一目標是只傳入包含兩個模型的List<Object> ,請傳遞List<Object>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM