Удаление элемента из адаптера выбрасывает индекс из привязанного исключения - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть два вида переработчика. Первое представление переработчика - это, в основном, список данных, в котором я могу выбрать элемент и его количество, и я сохраняю данные выбранного элемента на карте. Второй - список выбранных данных. который я генерирую из получения значений () с карты. У второго также есть похожий видоискатель, и я могу изменить количество там же. Как только количество достигает нуля, я удаляю элемент из списка и пытаюсь notifydatasetChanged ().

Проблема в том, что удаление элемента из второго списка не работает должным образом, и приложение вылетает с ошибкой

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder

Я использую интерфейс слушателя на моем первом Recycler, чтобы при изменении количества и добавлении элемента на карту. Адаптер второго ресайклера уведомляется об изменениях. ниже приведен код, который я использую для обновления второго представления переработчика.

public void updateList(){
        mMap = ((UserMainActivity)getActivity()).getItemMap();

        inputs.clear();
       // adapter.notifyDataSetChanged();

        adapter = new MyCartAdapter(inputs,getContext());
        cartList.setAdapter(adapter);
        for(AllItems t:mMap.values()) {
              inputs.add(t);
        }
        adapter.notifyDataSetChanged();
    }

Ниже представлен адаптер моего второго вида переработчика. Где я меняю количество выбранных предметов.

public class MyCartAdapter  extends RecyclerView.Adapter<MyCartAdapter.MyCartViewHolder>{
private List<AllItems> listItems1;
private Context context;
private Typeface typeface;



public MyCartAdapter(List<AllItems> listItems1, Context context) {
    this.listItems1 = listItems1;
    this.context = context;
}

@NonNull
@Override
public MyCartAdapter.MyCartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.cart_items_layout, parent, false);

    return new MyCartViewHolder(v);
}

@Override
public void onBindViewHolder(@NonNull final MyCartAdapter.MyCartViewHolder holder, final int position) {

    final AllItems orderItem = listItems1.get(position);
    holder.setProductImage(orderItem.getImageUrl(),context);
    holder.name.setText(orderItem.getName());
    String price = String.valueOf(orderItem.getPrice());
    holder.price.setText(price);

    final HashMap<String, AllItems> items = ((UserMainActivity)context).getItemMap();
    holder.counter.setText(orderItem.getQuantity());

    holder.add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String quantity = String.valueOf(holder.counter.getText());
            int count = Integer.parseInt(quantity)+1;
            holder.counter.setText(String.valueOf(count)); 
            String url = orderItem.getImageUrl();
            AllItems newitem = new AllItems(orderItem.getName(),orderItem.getComname(),url, String.valueOf(count),orderItem.getWeight,orderItem.getPrice());
            ((UserMainActivity)context).addItem(orderitemname,newitem);
          //  notifyItemChanged(position);
        }
    });
//counter text iitem.textview showing the quantity of the selected item . integer count returns the value of counter text below i am checking if its zero than it simply sets the value to zero and else reduce it and update the map.
    holder.minus.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String counterText = String.valueOf(holder.counter.getText());
            int count = Integer.parseInt(counterText);
            if (count==0){
                holder.counter.setText("0");
            }
            if (count==1){
                holder.counter.setText("0");
                AllItems item = items.get(orderItem.getName());
                if (item!=null){
                    String orderit = orderItem.getName();
                    ((UserMainActivity)context).removeItem(orderit);
// here i am removing the value from the list which throws the exception 
                    listItems1.remove(position);
                      notifyItemRemoved(position);
                }
            }
            if (count>1){
                String quantity = String.valueOf(count-1);
                holder.counter.setText(quantity);
                String orderitemname = orderItem.getName();
                String url = orderItem.getImageUrl();
                String weight = "100";
                long weightl = Long.parseLong(weight);
                AllItems newitem = new AllItems(orderItem.getName(),orderItem.getComname(),url, quantity,weight,orderItem.getPrice());
                ((UserMainActivity)context).addItem(orderitemname,newitem);
             //   listItems1.set(position, newitem);
             //   notifyItemChanged(position);

            }
        }
    });

}

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



public class MyCartViewHolder extends RecyclerView.ViewHolder {
    public TextView name,price,count,comname;
    public TextView weight;
    LinearLayout add,minus;
    TextView counter;

    public MyCartViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.ProName);
        price = (TextView) itemView.findViewById(R.id.proPrice);
        weight = (TextView) itemView.findViewById(R.id.ProWeight);
        counter = (TextView) itemView.findViewById(R.id.counter);
        add = (LinearLayout) itemView.findViewById(R.id.addLin);
        minus= (LinearLayout) itemView.findViewById(R.id.minusLin);
    }

    public void setProductImage(final String thumb_image, final Context ctx){
        productImage = (ImageView) itemView.findViewById(R.id.ProImage);
        Picasso.with(ctx).setIndicatorsEnabled(false);
        Picasso.with(ctx)
                .load(thumb_image)
                .networkPolicy(NetworkPolicy.OFFLINE)
                .placeholder(R.drawable.basket_b).into(productImage, new Callback() {
            @Override
            public void onSuccess() {
            }
            @Override
            public void onError() {
                Picasso.with(ctx).load(thumb_image).placeholder(R.drawable.basket).into(productImage);
            }
        });
 }
    public void setComname(String name){
        comname = (TextView)itemView.findViewById(R.id.proComName);
        comname.setText(name);
    }
}
}

1 Ответ

1 голос
/ 02 апреля 2019

Это выскакивает у меня:

listItems1.remove(position);
notifyItemChanged(position);

Метод notifyItemChanged() существует, чтобы сообщить адаптеру, что данные в данной позиции изменились, и что ViewHolder должен бытьповторно переплет.Это не , что вы делаете;Вы удаляете элемент.

Возможно, ваше приложение аварийно завершает работу, потому что вы удаляете последний элемент в вашем наборе данных (например, позиция 10), а затем сообщаете адаптеру, что элементпозиция 10 изменилась ... но теперь максимальная позиция в вашем наборе данных равна 9.

Вместо этого вам следует использовать метод notifyItemRemoved().

listItems1.remove(position);
notifyItemRemoved(position);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...