【问题标题】:how to create one recycler view adapter for multiple viewholders that matches a viewholder of choice not in the same recycler view list如何为多个查看器创建一个回收器视图适配器,该适配器与不在同一个回收器视图列表中的所选视图器匹配
【发布时间】:2018-07-05 12:22:38
【问题描述】:

我想知道如何创建一个包含多个视图持有者的回收器视图适配器,并且每次使用该适配器实例化 RecyclerView 时,我只想查看特定类型而不是混合类型。

我在 Android 活动中有 2 个不同的屏幕,每个屏幕都显示项目/卡片列表。一个是文本和数字,另一个是照片。现在我为每个对象有 2 个不同的自定义适配器,我想要实现的是一个适配器的灵活性,它可以根据屏幕显示的对象类型在对象类型之间进行延迟,并仅列出我需要的行。

我看到的所有例子都是混合类型的对象,这不是我所追求的。

适配器代码附在下面。

    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

【问题讨论】:

    标签: android android-recyclerview android-viewholder


    【解决方案1】:
    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);
            }
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      我不明白你的问题在哪里?您能否提供更多解释您想要实现的目标?

      // 编辑

      在您的代码中,您确定只有第一个项目是 VIEW0 类型的项目,其他项目将是 VIEW1。这是在getItemViewType(int position) 函数中。

      如果您想确定要选择的 ViewHolder,您必须在填充列表之前选择它。在您的适配器中创建枚举:

      enum TYPE {
          VIEW0,
          VIEW1
      }
      

      然后创建枚举变量:

      private TYPE itemType;
      

      并将其传递给您的构造函数:

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

      并检查您在onCreateViewHolder 函数中的开关中的类型(基于itemType 变量)。请注意,switch 中的变量是“itemType”,而不是 override 方法中的 viewType。

      @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));
      }
      
      }
      

      【讨论】:

      • 您可以将此添加为评论
      • 我无法添加 cmets,因为我没有 50 声望 :(
      • 显示照片会更容易,但我无法在此处上传照片。我的问题是我有 2 个对象,每个列表一个。正在构建的列表需要两个对象 os 它是这样的: 想要的列表1:A A A A A A A A 想要的列表2:B B B B B B B B 现实列表:A B A B A B A B
      • 我会在上面描述:)
      • @DennyDog 谢谢。我已经试过了。这都一样。我仍然得到混合列表。还有其他想法吗?
      猜你喜欢
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      • 1970-01-01
      • 2016-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多