RecyclerView多种视图类型(视图保持器)句柄项目选择计数状态

时间:2018-10-07 11:29:05

标签: android android-recyclerview recycler-adapter

我有一个带有标题标题和该类别下项目的recyclerview剖视图。我有两个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);
                }
            }
        });

}

View Holder 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,但视图被回收并项目计数放错了地方。

当我只有一个View Holder时,即只有View Holder 1,项目计数没有问题,但是当有2个View Holder时,它会被回收并放错位置。 我似乎不太了解我在做什么错。

此代码仅适用于单个Viewholder(单个项目类型RecyclerView)。

1 个答案:

答案 0 :(得分:2)

在屏幕上消失后,RecyclerView中的视图将被回收。您应该管理ViewHolder之外的状态,并将其用于演示。您可以将计数的当前值存储在传递给适配器的项目数据中,然后仅在ViewHolder中显示此当前值。

另一个重要的事情是始终设置该值。如果您未输入正确的值,则ViewHolder将保留回收的视图,因此,如果新单元格的计数为0,只需在绑定中输入0。

希望有帮助。