将 recyclerview click NOT 定义为构造函数的成员

define recyclerview click NOT as a member of constructor

通过阅读许多网站,我知道处理 recycerview 上的 onclick 的最佳方式是将 clicklistener 设置为不在 OnBindViewHolder 中,而是在 onCreateViewHolder 中(在 here) or pass the clickListener in "bind" method(explained in here 中解释)。

但真正困扰我的一件事是 clickListener 在 activity / fragment

中的处理方式
val adapter : MyAdapter(){
//click goes here
}

它可能不多,但老实说它不是那么可读

我更喜欢不在构造函数中处理点击侦听器,而是使用单独的方法,像这样的 meyabe

adapter.onItemClickListner = {
val adapter = MyAdapter()
//click more readable, yay!
}

但我不确定它是否会影响性能,或者我真的需要坚持点击构造函数吗?

我自己以前使用过这种方法。我没有在构造函数中传递侦听器,而是按照您描述的方法调用显式设置它。当我使用这种方法时,我必须确保在适配器中检查了侦听器的初始化及其空安全性。因此,在调用适配器中的侦听器方法之前,您必须确保它绝对存在并已初始化。

我逐渐转向构造函数,因为我不想在单击之前对我的适配器进行如此有意识的检查。 (当有多个可点击视图时。)

创建一个 interface,其中有一些 function 来处理您的 onClick。

现在你需要在你的 activity class 中 implement 这个 interface 像这样:-

class MainActivity : InterfaceAdapterOnClick(这里InterfaceAdapterOnClick是一个接口,它有一些函数来处理你的onClick

假设我们的 interface.

中有一个名为 onClickItemfunction

所以现在当你像这样创建你的适配器时 adapter = MyAdapter() 你可以通过它传递你的接口。所以它应该看起来像:-

var adapter = MyAdapter(this)this 因为您已经在 mainActivity class 中实现了 interface)并且您的适配器应该如下所示:-

class MyAdapter(onClickHandler: InterfaceAdapterOnClick) {}

所以最后你将在你的 mainActivity 中有一个单独的 interface 方法,你的 mainAcitvity 应该看起来像:-

class MainActivity : InterfaceAdapterOnClick {

    // This will be your seperate onClick handler for your recyclerView item

     override func onClickItem(// You can take some parameter as input here like `posistion` or `adapterItem` here ) {
    }
}

恕我直言,如果您的适配器需要 itemClickListener 才能正常运行,那么您应该通过其构造函数传递它并使用 setter 函数传递它并不好,因为您可能会忘记传递它有些时候你忘记传递监听器并浪费你的时间来检查为什么点击项目不起作用! (它发生在我身上:D)。如果您担心可读性,那么您可以使用接口并将实现传递给适配器,或者使用 Kotlin 的某些功能,如命名参数,或者传递函数的可调用引用以使其更具可读性。例如像这样的

class MyAdapter(onItemClick: (MyData) -> Unit) {
    // ...
}

并像这样初始化它

val adapter = MyAdapter(
    onItemClick = { data -> 
        // ...
    }
)

或者像这样传递函数

class MyActivity: AppCompatActivity() {

    override fun onCreateView(/**/) { 
        // ...

        val adapter = MyAdapter(
            onItemClick = ::onItemClick
        )
        // or
        // val adapter = MyAdapter(::onItemClick)
    }

    private fun onItemClick(data: MyData) {
    }
}

您可以简单地在 activity 和适配器 class 之间传递一个接口,但最好的方法是将一个函数传递给您的适配器 class,就像这样

     adapter = BasketRVA { basketEntity: BasketEntity, minus: Boolean -> changeQuantity(basketEntity, minus) }

       private fun changeQuantity(basketEntity: BasketEntity, minus: Boolean) {
///your code
}

并在适配器中键入此

class BasketRVA(private val clickListener: (BasketEntity, Boolean)->Unit): RecyclerView.Adapter<BasketRVA.BasketViewHolder>()

并在您的 viewHolder 中 class 和绑定函数

 inner class BasketViewHolder(binding: BasketItemBinding): RecyclerView.ViewHolder(binding.root) {
    @SuppressLint("SetTextI18n")
    fun bind(basketEntity: BasketEntity?, clickListener: (BasketEntity, Boolean) -> Unit){
        binding.tvProductName.text = basketEntity?.productName

在您的绑定函数中为您的视图创建一个点击侦听器并传递您要继续的函数

binding.imMinus.setOnClickListener {
            val minus = true
            clickListener(basketEntity!!, minus)
        }

在您的绑定 viewHolder 中

override fun onBindViewHolder(holder: BasketViewHolder, position: Int) {
    BasketViewHolder(binding).bind(basketList[position], clickListener)
    Log.d(TAG, "onBindViewHolder: basket list position is ${basketList[position]}")
}

还有什么问题可以问我