PHP User
PHP User

Reputation: 2422

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?

Upvotes: 0

Views: 56

Answers (4)

Hemal Patel
Hemal Patel

Reputation: 114

You can do this in three different way which is as below.

Method 1: Initialize your context in the constructor which you can create as below:

Context mContext;
List<Product> products

public ProductAdapter(Context mContext, List<Product> products) {
    super(context, 0, products);

    this.mContext = mContext;
    this.products = products;
}

And then this context as you use in your code.

Method - 2: Create your custom listener in your adapter and use it as below:

//Your interface in Adapter

private onItemViewClickListener itemViewClickListener;

//Your Custome Interface Define

public interface onItemViewClickListener{
       void onClick(View view, int position, Object object)
}

//Setter Method for your interface

public void setItemViewClickListener(onItemViewClickListener itemViewClickListener) {
        this.itemViewClickListener = itemViewClickListener;
}

//Your View Click Event where you have to set value as below:

convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (itemViewClickListener != null){
                    itemViewClickListener.onClick(v, position, object);
                }
            }
        });

Write above code in your adapter and below code in your activity or fragment where you are using your adapter for example if you are using this adapter in your activity you can use it in below two way.

TestAdapter adapter = new TestAdapter();
adapter.setItemViewClickListener(new TestAdapter.onItemViewClickListener() {
    @Override
    public void onClick(View view, int position, Object object) {
                //Here your logic
    }
});

Or if you implement your adapter interface in your activity class then you have to use below code and your click method will be overridden after implemented in a class where you can write your logic:

TestAdapter adapter = new TestAdapter();
adapter.setItemViewClickListener(this);

Upvotes: 0

Ridcully
Ridcully

Reputation: 23655

Your mContext is not initialized.

You can get the context from the view like so:

public void onClick(View v) {
        Toast.makeText(v.getContext(),"test", 
Toast.LENGTH_SHORT).show();
    }

Upvotes: 0

user4571931
user4571931

Reputation:

When you perform click event into listview or recyclerview that time create interface into adapter class like this way..

    onItemClickListner onItemClickListner;

public void setOnItemClickListner(CommentsAdapter.onItemClickListner onItemClickListner) {
    this.onItemClickListner = onItemClickListner;
}

public interface onItemClickListner {
    void onClick(int position);//pass your object types.
}

after that getView() in..

        buyNow.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onItemClickListner.onClick(position); // pass your data.
        }
    });

after that make adapter object and bind into listview after that called click event.. make sure your adapter not null

        adapter.setOnItemClickListner(new CommentsAdapter.onItemClickListner() {
        @Override
        public void onClick(int position) {
            // here show your toast or data
            adapter.notifyDataSetChanged();
        }
    });

Upvotes: 0

Pedro Massango
Pedro Massango

Reputation: 5015

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.

Upvotes: 1

Related Questions