Я пытаюсь вызвать другую функцию из своего адаптера просмотра ресайклера, я добавляю прослушиватель onclick в свой holder.itemView. Я пробовал setOnClickListener и onClick в своей деятельности с this@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
Я получаю контекст из конструктора в моем адаптере class NotesAdapter(private val context: Context) : RecyclerView.Adapter<NotesAdapter.NotesViewHolder>() {
Может попробовать это:
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])
}
})
}
Вместо этого вы хотели использовать чистый синтаксис Kotlins и передать ему лямбду. Что совершенно верно и намного чище. Однако похоже, что лямбда (или сопрограмма), по-видимому, также имеет поле с именем 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.
Вы можете объяснить, почему этот подход работает?
откуда вы берете контекст, который вы передаете в случае holder.itemView.onClick {showDialog (context, notes [position])}?