【问题标题】:Comparison of view.setOnLongClickListener and view.onClick in KotlinKotlin 中 view.setOnLongClickListener 和 view.onClick 的比较
【发布时间】:2018-12-18 04:32:03
【问题描述】:

我正在尝试从我的回收器视图适配器调用另一个函数,我在我的holder.itemView 中添加了 onclick 侦听器。我在我的活动中尝试了setOnClickListeneronClickthis@MainActivity 作为context 参数,效果很好。

btn.setOnClickListener { showDialog(this@MainActivity) }
btn.onClick { showDialog(this@MainActivity) }

但是onClick 在适配器中不起作用,因为

holder.itemView.setOnClickListener {
    showDialog(context, notes[position])
} // This works fine

// Type mismatch required Context, Found CoroutineContext
holder.itemView.onClick { showDialog(context, notes[position]) }

如果我想使用 onClick 而不是 setOnClickListener,我应该怎么做才能解决这个问题

【问题讨论】:

  • 你从哪里得到上下文,你通过 holder.itemView.onClick {showDialog(context, notes[position]) } ?
  • 我从适配器class NotesAdapter(private val context: Context) : RecyclerView.Adapter<NotesAdapter.NotesViewHolder>() {的构造函数中获取上下文

标签: android kotlin android-context


【解决方案1】:

不妨试试这个:

class NotesAdapter(private val ctx: Context) : RecyclerView.Adapter<NotesAdapter.NotesViewHolder>() {
    // Etc
    holder.itemView.onClick { showDialog(ctx, notes[position]) }
}

编辑 - 解释

无论如何,我都不是 Kotlin 方面的专家,但你得到的错误是关于发生了什么的非常清楚的线索。

当您在后台调用holder.itemView.onClick 时,您正在调用itemView.setOnClickListener,它采用View.OnClickListener 的实例。所以你可以做这样的事情,它可能会工作得很好:

class NotesAdapter(private val context: Context) : RecyclerView.Adapter<NotesAdapter.NotesViewHolder>() {
    // Etc
    holder.itemView.onClick(View.OnClickListener(){
        void onClick(v: View) {
            showDialog(context, notes[position])
        }
    })
}

相反,您想使用一些 Kotlin 的简洁语法并传递一个 lambda。这是完全有效的,而且更干净。但是,似乎 lambda(或协程)显然也有一个名为 context 的字段,并且它有一个 CoroutineContext 类型。继续上面的例子,它相当于:

holder.itemView.onClick(View.OnClickListener(){
    var context: CoroutineContext
    void onClick(v: View) {
        showDialog(context, notes[position])
    }
})

在这种情况下,当您调用 showDialog 时,您会得到当前范围的“上下文”,这是错误的类型,这就是您收到类型不匹配错误的原因。

在 java 中还有另一种解决方案,我只是不知道等效的 Kotlin 语法。你会做这样的事情:

holder.itemView.onClick { showDialog(NotesAdapter.this.context, notes[position]) }

这只是告诉编译器您正在寻找的上下文在 NotesAdapter 范围内而不是在 Coroutine 范围内的另一种方式

【讨论】:

  • 你能解释一下为什么这种方法有效吗?
猜你喜欢
  • 2020-06-22
  • 2016-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-06
  • 2020-09-10
  • 1970-01-01
相关资源
最近更新 更多