我已经通过recyclerview创建了一个购物车。每个viewholder也有一个+和-按钮来添加或删除数量。此功能是在适配器中完成的,我必须将更新后的总金额通知父片段。最后这一部分是通过接口完成的。问题是,我得到了以下错误:
Process: com.ecomm.market, PID: 6630
java.lang.NullPointerException: Attempt to invoke interface method 'void com.ecomm.market.SelectionAdapter$OnUpdateCartListener.onUpdateCart(int)' on a null object reference
at com.ecomm.market.SelectionAdapter$ViewHolder$1.onClick(SelectionAdapter.java:103)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
所选项目和相应数量存储在hashmap中,我将其转换为数组以填充回收器视图购物车。下面是我的主片段MenuFragment的相关部分:
// Using the adapter interface to add items to cart and adding up total amount
menuItemAdapter.setOnAddToCartListener(new MenuItemAdapter.OnAddToCartListener() {
@Override
public void onAddToCart(final HashMap selectionItemsHashMap) {
setupSelectionRecycler(menuView);
totalAmount = mapToArray(selectionItemsHashMap);
selectionAdapter = new SelectionAdapter(selectionItemArrayList, selectionItemsHashMap, totalAmount);
selectionRecycler.setAdapter(selectionAdapter);
cartItemsHashmap = selectionItemsHashMap;
selectionAdapter.setUpdateCartListener(new SelectionAdapter.OnUpdateCartListener() {
@Override
public void onUpdateCart(int updatedTotalAmount) {
String stringTotalAmount = Integer.toString(updatedTotalAmount);
Log.d(TAG, "received total:" +stringTotalAmount);
tvTotalAmount.setText("$"+ stringTotalAmount);
totalAmount = updatedTotalAmount;
}
});
}
});
}
下面是我的适配器SelectionAdapter的摘录
public class SelectionAdapter extends RecyclerView.Adapter<SelectionAdapter.ViewHolder> {
private static final String TAG = SelectionAdapter.class.getSimpleName();
private ArrayList<SelectionItem> selectionItemArrayList = new ArrayList<>();
public HashMap<String, Integer> selectionItemsHashMap = new HashMap<String, Integer>();
public int totalAmount;
private OnUpdateCartListener updateCartListener;
public interface OnUpdateCartListener {
void onUpdateCart(int totalAmount);
}
public void setUpdateCartListener(OnUpdateCartListener updateCartListener) {
this.updateCartListener = updateCartListener;
}
public SelectionAdapter(ArrayList<SelectionItem> selectionItemArrayList, HashMap<String, Integer> selectionItemsHashMap, int currentTotalAmount) {
this.selectionItemArrayList = selectionItemArrayList;
this.selectionItemsHashMap = selectionItemsHashMap;
this.totalAmount = currentTotalAmount;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.selection_card, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
viewHolder.tvSelectItem.setText(selectionItemArrayList.get(position).getSelectionName());
String quantity = Integer.toString(selectionItemArrayList.get(position).getSelectionQuantity());
viewHolder.tvDishQuantity.setText(quantity);
}
@Override
public int getItemCount() {
return selectionItemArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvSelectItem, tvDishQuantity;
ImageView addQuantity, subtractQuantity, deleteItem;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tvSelectItem = itemView.findViewById(R.id.dish_selection);
tvDishQuantity = itemView.findViewById(R.id.dish_quantity);
addQuantity = itemView.findViewById(R.id.button_add);
subtractQuantity = itemView.findViewById(R.id.button_subtract);
deleteItem = itemView.findViewById(R.id.delete_item);
addQuantity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Find the name of the menu item
int position = getAdapterPosition();
String itemName = selectionItemArrayList.get(position).getSelectionName();
// Increase quantity
int currentQuantity = selectionItemsHashMap.get(itemName);
currentQuantity += 1;
// Update the hashmap with the new quantity
selectionItemsHashMap.put(itemName,currentQuantity);
//Update total amount
for (Object name: selectionItemsHashMap.keySet()) {
String key = (String) name;
if (key.equals(selectionItemArrayList.get(position).getSelectionName())) {
int eachPrice = Integer.parseInt(selectionItemArrayList.get(position).getSelectionPrice());
totalAmount += eachPrice;
}
}
// Display the new quantity
String stringCurrentQuantity = Integer.toString(currentQuantity);
tvDishQuantity.setText(stringCurrentQuantity);
//updateCartListener.onUpdateCart(totalAmount);
}
});
}
编辑几个要点:-当购物车最初被填满时,我使用相同的代码,它工作得很好。-一旦用户返回购物车,并且我必须从捆绑包中重新填充它,问题就会发生。一切正常,除了当用户直接进入购物车并试图从那里改变数量时。
发布于 2019-05-30 12:47:12
将接口实现传入Adapter的构造函数,如下所示:
public SelectionAdapter(ArrayList<SelectionItem> selectionItemArrayList, HashMap<String, Integer> selectionItemsHashMap, int currentTotalAmount,UpdateCartListener updateCartListener ) {
this.selectionItemArrayList = selectionItemArrayList;
this.selectionItemsHashMap = selectionItemsHashMap;
this.totalAmount = currentTotalAmount;
this.updateCartListener = updateCartListener
}
这将在您的适配器初始化时提供接口的实现,因此当您将其用于更新购物车时,它将不为空。
发布于 2019-05-30 10:05:33
我猜您忘记在适配器中分配updateCartListener了。
SelectionAdapter(selectionItemArrayList, selectionItemsHashMap, totalAmount);
cartItemsHashmap = selectionItemsHashMap;
selectionAdapter.setUpdateCartListener(new SelectionAdapter.OnUpdateCartListener() {
@Override
public void onUpdateCart(int updatedTotalAmount) {
String stringTotalAmount = Integer.toString(updatedTotalAmount);
Log.d(TAG, "received total:" +stringTotalAmount);
tvTotalAmount.setText("$"+ stringTotalAmount);
totalAmount = updatedTotalAmount;
}
});
selectionRecycler.setAdapter(selectionAdapter);
发布于 2019-05-30 11:29:39
因此,您尝试访问ViewHolder
内的侦听器,这可能是导致崩溃的原因,标准方法是在适配器内设置OnClickListener
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
viewHolder.tvSelectItem.setText(selectionItemArrayList.get(position).getSelectionName());
String quantity = Integer.toString(selectionItemArrayList.get(position).getSelectionQuantity());
viewHolder.tvDishQuantity.setText(quantity);
viewHolder.addQuantity.setOnClickListener(new View.OnClickListener() {
...
}
}
https://stackoverflow.com/questions/56369909
复制相似问题