如何检查 recyclerview 适配器上的空侦听器?

Posted

技术标签:

【中文标题】如何检查 recyclerview 适配器上的空侦听器?【英文标题】:How to check for null listener on recyclerview adapter? 【发布时间】:2021-03-08 18:30:45 【问题描述】:

我遇到的问题是,当我单击适配器项时,传递给适配器类的侦听器为空,因此它永远不会触发任何东西。它确实通过调试向我显示正在单击某些内容。 我的父类是一个新的 kotlin 类,而适配器是一个旧的 java 类。我已将 java 类传递给 kotlin,但结果是一样的。

这是我的适配器类

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);
                
            
        );
    


onclicklistener 和 itemclicklistener 我都做了,它们都没有做任何事情。

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")
        
    )

任何帮助或建议都会很棒,谢谢!

我做了一个适配器 kotlin 类,试图只实现 OnClick 而不是 OnItemClick,但结果是一样的,一旦我点击它,监听器就为空

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 )
    

父类上的一个

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

【问题讨论】:

不要将 CustomerViewHolder 设为静态,所以它会保持对父级的引用...比您可以直接使用父类中的 mlistener 字段...或者从适配器的构造函数中删除 setter 和 set 字段 感谢您的回复。问题是适配器在另一个活动中使用,它工作正常,它的监听器也工作正常 你没有用 mListener 做任何事情,你想在哪里使用它。 感谢您的回复。我想要做的是当我单击列表中的一个项目时实现一个功能。我编辑了这个问题。我只是使用onclick事件添加了一个适配器kotlin类,但结果是一样的 【参考方案1】:

尝试在设置适配器之前将 onclicklistener 放在父类上

    customersAdapter = CustomersAdapter(customersList)

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

    rcvCustomer.adapter = customersAdapter

【讨论】:

【参考方案2】:

你也需要调用mListener

if (position != RecyclerView.NO_POSITION) 
    listener.onItemSelected(position);
    mListener.onItemSelected(position);

【讨论】:

感谢您的回复。它说 mListener 是一个未解决的参考。因为它没有在viewholder类上定义

以上是关于如何检查 recyclerview 适配器上的空侦听器?的主要内容,如果未能解决你的问题,请参考以下文章

RecyclerView 适配器中的空侦听器

如何防止android应用程序由于recyclerview中的空列表而崩溃? [复制]

RecyclerView 上的空指针

Android如何在CheckBox检查事件后更新RecyclerView内TextView的文本样式

尝试在 recyclerview kotlin 上的空对象引用上调用虚拟方法 'void android.widget.TextView.setText(java.lang.CharSequence)

如何从另一个项目更新recyclerview项目中的数据?