首页 > 解决方案 > 如何更新单个 RecyclerView 项目的计数器?

问题描述

我正在尝试制作一个食品订购系统。我正在显示 4 个单独的 recyclerview 项目,其中包含有关不同菜单选项的信息,并且能够选择其上的向上或向下箭头来更改特定项目的数量。我遇到的问题是,当我单击一个查看项目上的任一箭头时,它会更新列表中最低的项目(例如,如果我要单击顶部项目上的向上箭头,它会撞到底部项目向上一而不是)。我知道存在与此类似的问题,但我发现的解决方案都没有帮助或相关。

我尝试了几种不同的方法来改变值,我最初认为这是由于在适配器中使用了一个全局变量,但我改变了它,它什么也没做。我认为问题在于它没有区分项目,我不知道如何做到这一点。

这是我的适配器代码(为方便起见略作修剪):

public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.MenuViewHolder> {

    private Context context;
    private List<Food> foodList;
    private int userID;
    public MenuViewHolder holder;
    public int position;
    Food food;

    public MenuAdapter(Context context, List<Food> foodList, int userID) {
        this.context = context;
        this.foodList = foodList;
        this.userID = userID;
    }

    @NonNull
    @Override
    public MenuViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.menu_item_layout, null);
        return new MenuViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final MenuViewHolder thisHolder, int thisPosition) {

        holder = thisHolder;
        position = holder.getAdapterPosition();
        holder.itemView.setId(position);

        holder.upArrow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int currentValue = Integer.valueOf(holder.counter.getText().toString());
                int thisOrder = BumpCountUp(currentValue);
                holder.counter.setText(String.valueOf(thisOrder));
            }
        });

        holder.downArrow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int currentValue = Integer.valueOf(holder.counter.getText().toString());
                if(currentValue > 0) {
                    int thisOrder = BumpCountDown(currentValue);
                    holder.counter.setText(String.valueOf(thisOrder));
                }
            }
        });


    }

    public int BumpCountUp(int count) {
        int orderCount = count + 1;
        return orderCount;
    }


    public int BumpCountDown(int count) {
        int orderCount = count - 1;
        return orderCount;
    }

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


    class MenuViewHolder extends RecyclerView.ViewHolder {

        ImageView foodImage, upArrow, downArrow;
        TextView foodName, counter, price;
        RadioButton choice1, choice2, choice3;


        public MenuViewHolder(@NonNull View itemView) {
            super(itemView);

            counter = itemView.findViewById(R.id.counter);
            upArrow = itemView.findViewById(R.id.upArrow);
            downArrow = itemView.findViewById(R.id.downArrow);
        }
    }
}

这是活动的一个片段(我正在使用一个片段来包含回收视图):

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_order, container, false);


        List<Food> menuList = LoginActivity.tuckBoxDB.tbDao().getAllFoods();

        recyclerView = view.findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);

        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        adapter = new MenuAdapter(getContext(), menuList, userID);
        recyclerView.setAdapter(adapter);

    }

我希望这能够查看视图,找到分配给它的计数器,获取值,将其向上/向下增加 1,然后返回值并设置文本,这就是正在发生的事情,只是在错误的位置。

标签: androidandroid-recyclerview

解决方案


就 item 位置的错误解释RecyclerView而言,通常发生在它们内部的 valueonBindViewHolder()是 final 的时候。

我建议你从MenuAdapter类中删除这些成员变量。

public MenuViewHolder holder;
public int position;

当您想在内部类中使用 viewholder 和 position 的值时,您应该为这两个变量创建一个本地实例。在里面onBindViewHolder()你应该写:

MenuViewHolder holder = thisHolder;
int position = thisPosition;

onBindViewHolder()现在在内部类或内部类中使用这两个。如果需要,这些也可以是最终的,但参数onBindViewHolder()不应该是最终的,因为它会导致对位置和查看器项目的错误解释。


推荐阅读