how to create one recycler view adapter for multiple viewholders that matches a viewholder of choice not in the same recycler view list

天大地大妈咪最大 提交于 2020-06-28 04:50:22

问题


I would like to know how I can create ONE recycler view adapter that holds MULTIPLE view-holders and each time the RecyclerView is instantiated with that adapter,I want to see only a specific type rather than a mixed type.

I have 2 different screens in the Android activity and each of them shows a list of items/cards.One is of text and number and the other is a photo. Right now I have 2 different custom adapters for each object and what I want to achieve is the flexibility of one adapter that can defer between the types of objects according to the screen its displaying and list only the rows I need.

All the examples I've seen are of mixed type objects and it is not what I am after.

The Adapter code is appended below.

    public class MultiAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private ArrayList<MYDataProvider> arrayList;
    private final static int VIEW0 = 0;
    private final static int VIEW1 = 1;

    public MultiAdapter(ArrayList<MyDataProvider> _arrayList) {
        this.arrayList = new ArrayList<>();
        this.arrayList = _arrayList;
    }

    @Override
    public int getItemViewType(int position) {
        switch (position) {
            case 0:
                return VIEW0;

            case 1:
            default:
                return VIEW1;
        }//switch
    }//get item view type

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        int layoutRes;
        View view;
        RecyclerView.ViewHolder viewholder;

        switch (viewType) {
            case VIEW0:
                layoutRes = R.layout.card_item;
                view = LayoutInflater.from(viewGroup.getContext()).inflate(layoutRes, viewGroup, false);
                viewholder =  new E1(view);
                break;

            case VIEW1:
            default:
                layoutRes = R.layout.item_layout;
                view = LayoutInflater.from(viewGroup.getContext()).inflate(layoutRes, viewGroup, false);
                viewholder =  new E2(view);
                break;
        }//switch

        return viewholder;
    }//on create

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (holder.getItemViewType()) {
            case VIEW0: {
                MyDataProvider mydata = arrayList.get(position);
                ((E1)holder).name1.setText(mydata.getD_name() + "this is item " + position);
                ((E1)holder).imageView1.setImageResource(arrayList.get(position).getImg_res());
            }
            break;

            case VIEW1: {
                MyDataProvider mydata = arrayList.get(position);
                ((E2)holder).name2.setText(mydata.getD_name() + "this is item " + position);
                ((E2)holder).imageView2.setImageResource(arrayList.get(position).getImg_res());
            }
            break;
        }//switch
    }//on bind


    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    public class E1 extends mainViewHolder {
        ImageView imageView1;
        TextView name1;

        public E1(View itemView) {
            super(itemView);
            imageView1 = itemView.findViewById(R.id.image);
            name1 = itemView.findViewById(R.id.d_name);
        }
    }//e1 class

        public class E2 extends mainViewHolder {
        ImageView imageView2;
        TextView name2;

        public E2(View itemView) {
            super(itemView);
            imageView2 = itemView.findViewById(R.id.person_photo);
            name2 = itemView.findViewById(R.id.person_name);
        }
    }//e2 class

    public class mainViewHolder extends RecyclerView.ViewHolder {
        public mainViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }
}//adapter

回答1:


I don't get it where is your problem? Can you provide more explanation what you want to achieve?

// edit

In your code you determine that only first item will be item of type VIEW0 and others will be VIEW1. This is in getItemViewType(int position) function.

If you want determine what ViewHolder to pick you must to choose it before you populate list. Create enum in your adapter:

enum TYPE {
    VIEW0,
    VIEW1
}

then create variable of enum:

private TYPE itemType;

and pass it in your constructor:

public Test(ArrayList<MyDataProvider> _arrayList, TYPE itemType) {
    this.arrayList = new ArrayList<>();
    this.arrayList = _arrayList;
    this.itemType = itemType;
}

and check what is your type (based on itemType variable) in your switch in onCreateViewHolder function like that. Note that variable in switch is "itemType", not viewType from override method.

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (itemType) {
    case VIEW0:
        return new NotificationsAdapter.ReferralTriggerViewHolder(inflater.inflate(R.layout.row_referral_trigger, parent, false));
    case VIEW1:
        return new NotificationsAdapter.UserNotificationViewHolder(inflater.inflate(R.layout.row_layout_user_notification, parent, false));
    default:
        return new NotificationsAdapter.UserNotificationViewHolder(inflater.inflate(R.layout.row_layout_user_notification, parent, false));
}

}



回答2:


public class NotificationsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int VIEW_TYPE_REFERRAL_TRIGGER = 1;
    private static final int VIEW_TYPE_NOTIFICATION = 2;
    private static final int VIEW_TYPE_PROMOTION = 3;

    private List<Object> notificationObjectsList;
    private Activity mActivity;

    public NotificationsAdapter(Activity activity, List<Object> mNotificationList) {
        mActivity = activity;
        notificationObjectsList = new ArrayList<>(mNotificationList);
    }


    // Used to avoid the duplicate items recycling
    @Override
    public long getItemId(int position) {
        return position;
    }

    // Used to avoid the duplicate items recycling
    @Override
    public int getItemViewType(int position) {

        if ((notificationObjectsList.get(position) != null) && (notificationObjectsList.get(position) instanceof ReferralData)) {
            return VIEW_TYPE_REFERRAL_TRIGGER;
        } else if (notificationObjectsList.get(position) instanceof Promotion) {
            return VIEW_TYPE_PROMOTION;
        } else {
            return VIEW_TYPE_NOTIFICATION;
        }

    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        switch (viewType) {
            case VIEW_TYPE_REFERRAL_TRIGGER:
                return new NotificationsAdapter.ReferralTriggerViewHolder(inflater.inflate(R.layout.row_referral_trigger, parent, false));
            case VIEW_TYPE_NOTIFICATION:
                return new NotificationsAdapter.UserNotificationViewHolder(inflater.inflate(R.layout.row_layout_user_notification, parent, false));
            case VIEW_TYPE_PROMOTION:
                return new NotificationsAdapter.PromotionViewHolder(inflater.inflate(R.layout.row_layout_app_promotions, parent, false));
            default:
                return new NotificationsAdapter.UserNotificationViewHolder(inflater.inflate(R.layout.row_layout_user_notification, parent, false));
        }

    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {

        if (viewHolder instanceof PromotionViewHolder) {
            final PromotionViewHolder promotionViewHolder = (PromotionViewHolder) viewHolder;
            //populate data of promotion view holder

        } else if (viewHolder instanceof UserNotificationViewHolder) {
            final UserNotificationViewHolder notificationViewHolder = (UserNotificationViewHolder) viewHolder;
            //populate data of UserNotificationViewHolder view holder

        } else if (viewHolder instanceof ReferralTriggerViewHolder) {
            final ReferralTriggerViewHolder referralTriggerViewHolder = (ReferralTriggerViewHolder) viewHolder;
            //populate data of ReferralTriggerViewHolder view holder
        }
    }

    @Override
    public int getItemCount() {
        return notificationObjectsList.size();
    }


    private class UserNotificationViewHolder extends RecyclerView.ViewHolder {

        private UserNotificationViewHolder(View itemView) {
            super(itemView);

        }


    }

    private class PromotionViewHolder extends RecyclerView.ViewHolder  {

        private PromotionViewHolder(View itemView) {
            super(itemView);
        }


    }

    private class ReferralTriggerViewHolder extends RecyclerView.ViewHolder {
        ReferralTriggerView referralTriggerView;

        private ReferralTriggerViewHolder(View itemView) {
            super(itemView);
            referralTriggerView = itemView.findViewById(R.id.rtv_notification_adapter);
        }
    }

}


来源:https://stackoverflow.com/questions/51191230/how-to-create-one-recycler-view-adapter-for-multiple-viewholders-that-matches-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!