This is the error I am getting:
Process: com.painlessshopping.mohamed.findit, PID: 21324 java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.view.ViewGroup.getContext()' on a null object reference at android.support.design.widget.Snackbar.<init>(Snackbar.java:192) at android.support.design.widget.Snackbar.make(Snackbar.java:224) at com.painlessshopping.mohamed.findit.CartAdapter$1.onClick(CartAdapter.java:100) at android.view.View.performClick(View.java:5201) at android.view.View$PerformClick.run(View.java:21163) at android.os.Handler.handleCallback(Handler.java:746) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5443) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
And here is the code for my CartAdapter
Class:
public class CartAdapter extends ArrayAdapter<Item> implements View.OnClickListener{
private ArrayList<Item> dataSet;
Context mContext;
// View lookup cache
private static class ViewHolder {
TextView itemTitle;
TextView itemStore;
TextView itemPrice;
ImageView storeLogo;
ImageView removeFromCart;
}
public CartAdapter (ArrayList<Item> data, Context context) {
super(context, R.layout.row_cart, data);
this.dataSet = data;
this.mContext=context;
}
@Override
public void onClick(View v) {
int position=(Integer) v.getTag();
Object object= getItem(position);
final Item item=(Item)object;
CharSequence actions[];
final View view = v;
switch (v.getId())
{
case R.id.more:
System.out.println(item.getLink());
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(item.getLink()));
mContext.startActivity(browserIntent);
break;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
final Item item = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
final View result;
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_cart, parent, false);
viewHolder.itemTitle = (TextView) convertView.findViewById(R.id.title);
viewHolder.itemStore = (TextView) convertView.findViewById(R.id.retailer);
viewHolder.itemPrice = (TextView) convertView.findViewById(R.id.price);
viewHolder.storeLogo = (ImageView) convertView.findViewById(R.id.more);
viewHolder.removeFromCart = (ImageView) convertView.findViewById(R.id.removeCart);
result = convertView;
convertView.setTag(viewHolder);
viewHolder.itemTitle.setText(item.getTitle());
viewHolder.itemStore.setText("From " + item.getStore());
viewHolder.itemPrice.setText("$" + item.getPrice());
viewHolder.storeLogo.setOnClickListener(this);
viewHolder.removeFromCart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CartInfoProvider.removeFromCart(item);
MyCart.adapter.remove(item);
MyCart.adapter.notifyDataSetChanged();
Snackbar.make(result, "This item was removed from your cart", Snackbar.LENGTH_INDEFINITE).setAction("UNDO", new View.OnClickListener() {
@Override
public void onClick(View v) {
CartInfoProvider.addToCart(item);
MyCart.adapter.add(item);
MyCart.adapter.notifyDataSetChanged();
}
}).show();
}
});
viewHolder.storeLogo.setTag(position);
// Return the completed view to render on screen
return convertView;
}
}
And here is the onCreate
for my CartActivity
:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_cart);
ListView listView=(ListView)findViewById(R.id.cart);
adapter= new CartAdapter(Items, this);
listView.setAdapter(adapter);
TextView empty = (TextView) findViewById(R.id.empty);
listView.setEmptyView(empty);
adapter.addAll(CartInfoProvider.getCart());
adapter.notifyDataSetChanged();
}
The functionality works perfectly when there is more than 1 item in the cart. But when I try to remove the FINAL item from the cart, the app crashes and throws the above error. Any Ideas? I don't know what's wrong.
Edit: I'm assuming that someone's going to ask me to provide the code for CartInfoProvider
so here it is:
public class CartInfoProvider {
private static ArrayList<Item> cart = new ArrayList<Item>();
public static void addToCart(Item i){
cart.add(i);
}
public static void removeFromCart(Item i){
cart.remove(i);
}
public static ArrayList<Item> getCart(){
return cart;
}
}
As @CommonsWare said, I should've been using my listView instead of the actual row to display the snackbar. This is because when I remove the row the snackbar is trying to attach itself to something that doesn't exist, hence the nullpointer.
To fix this, I just changed the constructor of my adapter to read in the listview and then used that for my snackbar. Cheers!