如何为多个查看器创建一个回收器视图适配器,以匹配不在同一回收器视图列表中的所选查看器
how to create one recycler view adapter for multiple viewholders that matches a viewholder of choice not in the same recycler view list
我想知道如何创建一个包含多个视图持有者的回收器视图适配器,并且每次使用该适配器实例化 RecyclerView 时,我只想查看特定类型而不是混合类型。
我在 Android activity 中有 2 个不同的屏幕,每个屏幕都显示 items/cards 的列表。一个是文本和数字,另一个是照片。现在我有 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
我不明白你的问题在哪里?您能否提供更多说明您想要实现的目标?
// 编辑
在您的代码中,您确定只有第一个项目是 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));
}
}
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);
}
}
}
我想知道如何创建一个包含多个视图持有者的回收器视图适配器,并且每次使用该适配器实例化 RecyclerView 时,我只想查看特定类型而不是混合类型。
我在 Android activity 中有 2 个不同的屏幕,每个屏幕都显示 items/cards 的列表。一个是文本和数字,另一个是照片。现在我有 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
我不明白你的问题在哪里?您能否提供更多说明您想要实现的目标?
// 编辑
在您的代码中,您确定只有第一个项目是 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));
}
}
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);
}
}
}