android - RecyclerView 多种视图类型(View Holders)处理项选择计数状态
问题描述
我有一个分段的 recyclerview,其中包含标题标题和该 catergoty 下的项目。我有两个 viewHolders 一个用于标题,另一个用于该类别下的项目。这是我的适配器。
public class MenuAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final String TAG = MenuAdapter.class.getSimpleName();
private Context mContext;
private ItemClickListener itemClickListener;
private List<HeterogeneousObject> heterogeneousObjects;
public MenuAdapter(Context mContext, CartHelper helper) {
this.mContext = mContext;
heterogeneousObjects = new ArrayList<>();
}
public void itemClickListenerCallback(ItemClickListener itemClickListenerCallback) {
this.itemClickListener = menuItemClickListenerCallback;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == 0) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_single_cuisine_rv, parent, false);
return new MenuAdapterViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_single_cuisine_menu_items, parent, false);
return new RecycledGridViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
HeterogeneousObject object = heterogeneousObjects.get(position);
if (object.getItemType() == 0) {
if (object.getCuisine() != null) {
MenuAdapterViewHolder holder = (MenuAdapterViewHolder) viewHolder;
holder.cuisineName.setText(object.getCuisine().getCuisine_name());
}
} else {
if (object.getMenuItem() != null) {
RecycledGridViewHolder holder = (RecycledGridViewHolder) viewHolder;
holder.dishName.setText(object.getMenuItem().getItemName());
holder.dishPrice.setText(mContext.getString(R.string.rupee_symbol, object.getMenuItem().getItemPrice() * 0.01));
if (object.getMenuItem().getIsVeg()) {
holder.vegNonVegIndicator.setImageDrawable(mContext.getResources().getDrawable(R.drawable.veg_symbol));
//holder.vegNonVegIndicator.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_veg_indicator));
} else if (!object.getMenuItem().getIsVeg()) {
holder.vegNonVegIndicator.setImageDrawable(mContext.getResources().getDrawable(R.drawable.non_veg_symbol));
//holder.vegNonVegIndicator.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_non_veg_indicator));
}
Single<CartSelection> selection = cartHelper.getCartSelectionById(Long.parseLong(object.getMenuItem().getItemId()));
selection.subscribe(new DisposableSingleObserver<CartSelection>() {
@Override
public void onSuccess(CartSelection cartSelection) {
if (cartSelection != null) {
holder.incDecButton.setNumber(cartSelection.getQty(), true);
}
}
@Override
public void onError(Throwable e) {
}
});
holder.bind(object.getMenuItem(), menuItemClickListener);
}
}
}
@Override
public int getItemCount() {
return heterogeneousObjects.size();
}
@Override
public int getItemViewType(int position) {
super.getItemViewType(position);
if (heterogeneousObjects.get(position).getItemType() == 0) {
return 0;
} else {
return 1;
}
}
}
这是我的视图支架 1
public class RecycledGridViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.tv_si_dish_name)
TextView dishName;
@BindView(R.id.tv_si_dish_price)
TextView dishPrice;
@BindView(R.id.btn_id_item_dish_grid)
IncDecButton incDecButton;
@BindView(R.id.iv_veg_non_veg_grid)
AppCompatImageView vegNonVegIndicator;
public RecycledGridViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void bind(final MenuItem menuItem, final MenuItemClickListener menuItemClickListener) {
incDecButton.setOnButtonsClickedListener(new IncDecButton.OnButtonsClickedListener() {
@Override
public void onPlusClicked(int num) {
if (menuItem.getCustomizable()) {
menuItemClickListener.onCustomizableItemClicked(menuItem, 1);
if (incDecButton.getNumber() == 0) {
incDecButton.setNumber(0, true);
}
} else {
menuItemClickListener.onPlusButtonClicked(menuItem, num);
}
}
@Override
public void onMinusClicked(int num) {
if (menuItem.getCustomizable()) {
menuItemClickListener.onCustomizableItemClicked(menuItem, 0);
} else {
menuItemClickListener.onMinusButtonClicked(menuItem, num);
}
}
});
}
查看支架 2
class MenuAdapterViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.tv_cuisine_name_menu_v2)
TextView cuisineName;
public MenuAdapterViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
我正在维护一个项目计数状态,即 ViewHolder 1 中的列表项必须显示在 ROOM Db Dao 中 ViewHolder 之外的 IncDecButton 中,我查询它,因为每个项目都调用了 onBindViewHolder,但视图被回收并且项目计数得到放错地方了。
当我只有一个视图持有者时,即只有视图持有者 1,项目计数没有问题,但是当有 2 个视图持有者时,它会被回收并放错位置。我似乎真的不明白我做错了什么。
此代码仅适用于单个 Viewholder(单项类型 RecyclerView)。
解决方案
a 中的视图在RecyclerView
屏幕中消失时会被回收。您应该管理外部的状态ViewHolder
并将其用于演示。您可以将计数的当前值存储在传递给适配器的项目数据中,然后在ViewHolder
.
另一个重要的事情是始终设置值。如果你没有输入正确的值,ViewHolder
将保持回收的视图,所以如果新单元格的计数为 0,只需将 0 放入绑定中。
希望能帮助到你。
推荐阅读
- html - 如何使用多个音频标签
- next.js - 如何在 nextjs 中检查每个请求的 cookie?
- php - 无法理解 php 中对象和数组的逻辑
- json - 我正在尝试将亚马逊交易作为 Acumatica 销售订单导入,但遇到 500 错误
- python - 在 Python 中创建登录系统
- java - Java ArrayBlockingQueue 阻塞,直到队列中有东西
- reactjs - 在react.js中登录和注销时重新渲染链接
- python - 8.22 Python IT17:替换词
- c# - Prism IDialogService 显示非模态对话框充当模态
- c# - 发现无法解决的“System.Runtime.CompilerServices.Unsafe”不同版本之间的冲突