androidkotlinandroid-recyclerviewonclicklisteneronitemselectedlistener

How to check for null listener on recyclerview adapter?


the problem I have is that when I click on my adapter item, the listener passed to the adapter class is null so it never triggers anything. It does show me via debbug that something is being clicked. My parent class is a new kotlin class and the adapter is an old java class. I have pass the java class to kotlin but the result is the same.

This is my adapter class

public class CustomersAdapter extends RecyclerView.Adapter<CustomersAdapter.CustomerViewHolder> implements View.OnClickListener {

private List<Customer> customers;
private View.OnClickListener listener;
private CustomersAdapter.OnItemClickListener mListener;

public CustomersAdapter(List<Customer> customer){
    customers = customer;
}

@NonNull
@Override
public CustomerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.adapter_customers, viewGroup, false);
    v.setOnClickListener(this);
    return new CustomerViewHolder(v,mListener);
}

@Override
public void onBindViewHolder(@NonNull CustomerViewHolder customerViewHolder, int i) {
    customerViewHolder.txtCustomerName.setText(customers.get(i).custName1+" "+customers.get(i).custName2+" "+customers.get(i).custLastName1+" "+customers.get(i).custLastName2);
    customerViewHolder.txtCustomerNickname.setText(customers.get(i).custNickName);
}

@Override
public int getItemCount() {
    return customers.size();
}

public void setOnClickListener(View.OnClickListener listener){
    this.listener = listener;
}

public interface OnItemClickListener{
    void onItemSelected(int position);
}

public void setOnItemClickListener(CustomersAdapter.OnItemClickListener listener) {
    mListener = listener;
}

@Override
public void onClick(View v) {
    if(listener != null){
        listener.onClick(v);
    }
}

static class CustomerViewHolder extends RecyclerView.ViewHolder {
    TextView txtCustomerName;
    TextView txtCustomerNickname;
    LinearLayout lytCustomerInfo;

    CustomerViewHolder(View itemView, final CustomersAdapter.OnItemClickListener listener) {
            super(itemView);
        lytCustomerInfo  = itemView.findViewById(R.id.lytCustomerInfo);
        txtCustomerName = itemView.findViewById(R.id.txtNameCustomerAdapter);
        txtCustomerNickname = itemView.findViewById(R.id.txtNicknameCustomerAdapter);
        lytCustomerInfo.setOnClickListener(v -> {
            if (listener != null) {
                int position = getAdapterPosition();
                if (position != RecyclerView.NO_POSITION) {
                    listener.onItemSelected(position);
                }
            }
        });
    }

}

}

I have made both onclicklistener and itemclicklistener, and none of them is doing anything.

val customer = Customer()
        customersList = if (filter.trim { it <= ' ' } == "") ArrayList() else customer.getCustomers(filter)

    customersAdapter = CustomersKtAdapter(context, customersList)

    rcvCustomer.adapter = customersAdapter

    customersAdapter.setOnClickListener { v ->
        Log.d("TAG", "message")
    }

    customersAdapter!!.setOnItemClickListener( object: CustomersAdapter.OnItemClickListener {
        override fun onItemSelected(position: Int) {
            Log.d("TAG", "message")
        }
    })

Any help or suggestion would be great, thanks!

I have made an adapter kotlin class trying to implement just OnClick not OnItemClick, but the result is the same, the listener is null once I click it

class CustomersKtAdapter(applicationContext: Context, customerList: MutableList<Customer>) : RecyclerView.Adapter<CustomersKtAdapter.CustomersKtViewHolder?>(), View.OnClickListener{

private var listener: View.OnClickListener? = null

var context: Context? = null
private var defaultFormat: NumberFormat? = null
var inflater: LayoutInflater? = null

var customerList: List<Customer>? = null

init {
    this.context = applicationContext
    this.customerList = customerList
    defaultFormat = NumberFormat.getCurrencyInstance()
    inflater = LayoutInflater.from(context)
}

override fun onCreateViewHolder(parent: ViewGroup, p1: Int): CustomersKtViewHolder {
    //inflate view
    val v: View = LayoutInflater.from(parent.context).inflate(R.layout.adapter_customers, parent, false)
    v.setOnClickListener(this)
    return CustomersKtViewHolder(v)

}

override fun getItemCount(): Int {
    return customerList!!.size
}

override fun onBindViewHolder(holder: CustomersKtViewHolder, position: Int) {
    holder.txtNicknameCustomerAdapter!!.text = customerList?.get(position)?.custNickName
    holder.txtNameCustomerAdapter!!.text = customerList?.get(position)?.custName1

}

override fun onClick(view: View?) {
    listener?.onClick(view)
}

fun setOnClickListener(listener: View.OnClickListener?) {
    this.listener = listener
}

    class CustomersKtViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    
    var txtNicknameCustomerAdapter: TextView? = null
    var txtNameCustomerAdapter: TextView? = null

    init {
        txtNicknameCustomerAdapter  = itemView.findViewById(R.id.txtNicknameCustomerAdapter )
        txtNameCustomerAdapter  = itemView.findViewById(R.id.txtNameCustomerAdapter )
    }
}

}

an on the parent class

    customersAdapter!!.setOnClickListener(View.OnClickListener { v ->
        Log.d("TAG", "message")
    })

Solution

  • Try put the onclicklistener on the parent class before you set the adapter

        customersAdapter = CustomersAdapter(customersList)
    
        customersAdapter!!.setOnClickListener(View.OnClickListener { v ->
            Log.d("TAG", "message")
        })
    
        rcvCustomer.adapter = customersAdapter