Search code examples
androidonclicklistenercustom-adapter

Attaching a ClickListener to a list item button click in a custom adapter


I have this custom adapter

public class ProductAdapter extends ArrayAdapter<Product> {

Context mContext;

public ProductAdapter(Activity context, ArrayList<Product> products) {
    super(context, 0, products);
}

@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View listItemView = convertView;
    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(
                R.layout.list_item, parent, false);
    }

    Product currentProduct = getItem(position);

    TextView nameTextView = (TextView) listItemView.findViewById(R.id.product_name);

    nameTextView.setText(currentProduct.getProductName());

    TextView numberTextView = (TextView) listItemView.findViewById(R.id.product_price);

    numberTextView.setText("$"+currentProduct.getProductPrice());

    ImageView iconView = (ImageView) listItemView.findViewById(R.id.list_item_icon);

    iconView.setImageResource(currentProduct.getProductImage());

    Button buyNow = (Button) listItemView.findViewById(R.id.buy_now);

    buyNow.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(mContext,"test", Toast.LENGTH_SHORT).show();
        }
    });

    return listItemView;
  }
}

And this button in list_item

<Button
        android:id="@+id/buy_now"
        android:text="Buy Now"
        style="@style/listBtn" />

As you can see I have defined mContext as Context to use it inside the adapter.

Clicking the button makes the app closes and it doesn't work. How to create onClickListener in the custom adapter in a correct way?


Solution

  • Looks like your mContext is null (I guess) because it seems like you did not instantiate it anywhere.

    Try this code (you can copy/paste)

    public class ProductAdapter extends ArrayAdapter<Product> {
    
    // Use getContext() instead of this property
    //Context mContext;
    
    public ProductAdapter(Activity context, ArrayList<Product> products) {
        super(context, 0, products);
    }
    
    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    
        View listItemView = convertView;
        if (listItemView == null) {
            listItemView = LayoutInflater.from(getContext()).inflate(
                    R.layout.list_item, parent, false);
        }
    
        Product currentProduct = getItem(position);
    
        TextView nameTextView = (TextView) listItemView.findViewById(R.id.product_name);
    
        nameTextView.setText(currentProduct.getProductName());
    
        TextView numberTextView = (TextView) listItemView.findViewById(R.id.product_price);
    
        numberTextView.setText("$"+currentProduct.getProductPrice());
    
        ImageView iconView = (ImageView) listItemView.findViewById(R.id.list_item_icon);
    
        iconView.setImageResource(currentProduct.getProductImage());
    
        Button buyNow = (Button) listItemView.findViewById(R.id.buy_now);
    
        buyNow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(),"test", Toast.LENGTH_SHORT).show();
            }
        });
    
        return listItemView;
      }
    }
    

    Nate that I just removed your mContext property because you can just use getContext() anywhere inside of your adapter.