代码之家  ›  专栏  ›  技术社区  ›  Taufiq Rahman

调用notifyitemsetchanged()后,RecyclerView适配器数据正在重置

  •  2
  • Taufiq Rahman  · 技术社区  · 7 年前

    我有一个购物车,我想增加/减少按钮点击项目的数量。我可以看到应用程序正在进行更改,但当它更改回默认值时,可能是由于notifyitemsetchanged()?请检查onClick(),我不知道为什么它会“重置”为默认值,而我增加了值,但它在一秒钟内就变回来了:

    适配器:

    public class CartRecyclerAdapter extends RecyclerView.Adapter<CartRecyclerAdapter.MyViewHolder>  {
    
    Context context;
    String json;
    ListSharedPreference.Get getSharedPreference;
    
    public CartRecyclerAdapter(Context context, String json) {
        this.context = context;
        this.json = json;
        getSharedPreference = new ListSharedPreference.Get(context);
    }
    
    public static <T> List<T> stringToArray(String s, Class<T[]> clazz) {
        return Arrays.asList(new Gson().fromJson(s, clazz));
    }
    
    public void setItemList(String itemList) {
        this.itemList = itemList;
        notifyDataSetChanged();
    }
    
    @Override
    public CartRecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cart, parent, false);
        return new CartRecyclerAdapter.MyViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(CartRecyclerAdapter.MyViewHolder holder, int position) {
        holder.title.setText(stringToArray(json, RestaurantModel.Menu[].class).get(position).getFoodtitle());
        holder.price.setText(String.format("%d USD", stringToArray(json, RestaurantModel.Menu[].class).get(position).getPrice()));
        holder.quantity.setText(String.valueOf(stringToArray(json, RestaurantModel.Menu[].class).get(position).getQuantity()));
    }
    
    @Override
    public int getItemCount() {
        if (itemList != null) {
            return stringToArray(json, RestaurantModel.Menu[].class).size();
        }
        return 0;
    }
    
    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView title;
        TextView price;
        TextView quantity;
        Button add;
    
        public MyViewHolder(View itemView) {
            super(itemView);
            title = (TextView) itemView.findViewById(R.id.cardView_name);
            price = (TextView) itemView.findViewById(R.id.item_price);
            add = (Button) itemView.findViewById(R.id.add_button);
            quantity = (TextView) itemView.findViewById(R.id.quantity);
    
            add.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.add_button:
                    int i = Integer.parseInt(quantity.getText().toString());
                    i++;
                    quantity.setText(String.valueOf(i));
                    stringToArray(json, RestaurantModel.Menu[].class).get(getAdapterPosition()).setQuantity(i);
                    notifyItemChanged(getAdapterPosition());
                    break;
            }
        }
    }
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Anatolii    7 年前

    问题是每次你打电话 stringToArray() json 反对。显然,这个新数组有所有默认值,但是 Adapter 基于它们重新绑定视图。这就是为什么您需要一个数组,以便每次更改其元素并调用 notifyItemChanged()/notifyDataSetChanged() onBindViewHolder 从它而不是其他数组中检索值。可能如下所示:

    public class CartRecyclerAdapter extends RecyclerView.Adapter<CartRecyclerAdapter.MyViewHolder>  {    
        Context context;
        private List<RestaurantModel.Menu> menus = new ArrayList<>();
        ListSharedPreference.Get getSharedPreference;
    
        public CartRecyclerAdapter(Context context, String json) {
            this.context = context;
            menus = stringToArray(json, RestaurantModel.Menu[].class);
            getSharedPreference = new ListSharedPreference.Get(context);
        }
    
        public static <T> List<T> stringToArray(String s, Class<T[]> clazz) {
            return Arrays.asList(new Gson().fromJson(s, clazz));
        }
    
        public void setItemList(String itemList) {
            menus = stringToArray(json, RestaurantModel.Menu[].class);
            notifyDataSetChanged();
        }
    
        @Override
        public CartRecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cart, parent, false);
            return new CartRecyclerAdapter.MyViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(CartRecyclerAdapter.MyViewHolder holder, int position) {
            holder.title.setText(menus.get(position).getFoodtitle());
            holder.price.setText(String.format("%d USD", menus.get(position).getPrice()));
            holder.quantity.setText(String.valueOf(menus.get(position).getQuantity()));
        }
    
        @Override
        public int getItemCount() {
            menus.size();
        }
    
        public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
            TextView title;
            TextView price;
            TextView quantity;
            Button add;
    
            public MyViewHolder(View itemView) {
                super(itemView);
                title = (TextView) itemView.findViewById(R.id.cardView_name);
                price = (TextView) itemView.findViewById(R.id.item_price);
                add = (Button) itemView.findViewById(R.id.add_button);
                quantity = (TextView) itemView.findViewById(R.id.quantity);
    
                add.setOnClickListener(this);
            }
    
            @Override
            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.add_button:
                        int i = Integer.parseInt(quantity.getText().toString());
                        i++;
                        menus.get(getAdapterPosition()).setQuantity(i);
                        notifyItemChanged(getAdapterPosition());
                        break;
                }
            }
        }
    }