我有两个回收站视图。第一个recyclerview基本上是一个数据列表,在这里我可以选择一个项目及其数量,并将这个选择的项目数据存储到地图中。第二个是所选数据的列表。这是我从地图上获取values()生成的。第二个也有类似的viewholder,我也可以在那里更改数量。当数量达到零时,我将其从列表中删除,然后尝试通知notifydatasetChanged()。
问题是从第二个列表中删除项目无法正常工作,并且应用程序因错误而崩溃
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
我在第一个回收站上使用侦听器界面,以便在更改数量并将项目添加到地图时使用。更改将通知第二个回收站的适配器。下面是我用来更新第二个回收站视图的代码。
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);
}
}
}
答案 0 :(得分:1)
这对我跳了起来
listItems1.remove(position); notifyItemChanged(position);
存在notifyItemChanged()
方法来告诉适配器给定位置的数据已更改,并且ViewHolder应该重新绑定。这不是您所做的不是;您正在删除一个项目。
您的应用程序可能崩溃了,因为您要删除数据集中的最后一个项目(例如位置10),然后告诉适配器位置10的项目已更改...但是现在数据集中的最大位置是9。
相反,您应该使用notifyItemRemoved()
方法。
listItems1.remove(position);
notifyItemRemoved(position);