Przekazać do do adaptera interfejs, który będzie delegował do view modelu. Czyli coś w tym stylu.
class NoteAdapter(
private val listener: Listener,
): ListAdapter<Note, NoteViewHolder>(DiffCallback) {
override fun getItemViewType(position: Int) = R.layout.note_view_holder_layout
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder {
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
return NoteViewHolder(view, listener)
}
override fun onBindViewHolder(holder: NoteViewHolder, position: Int) = holder.bind(getItem(position))
interface Listener {
fun onDeleteNote(note: Note)
}
private object DiffCallback : ItemCallback<Note>() {
override fun areItemsTheSame(old: Note, new: Note) = old.id == new.id
override fun areContentsTheSame(old: Note, new: Note) = old == new
// Opcjonalnie dla unikania mrugających animacji, jeśli masz z tym problem.
override fun getChangePayload(old: Note, new: Note) = Unit
}
}
class NoteViewHolder(
itemView: View,
private val listener: NoteAdapter.Listener,
) : ViewHolder(itemView) {
private var note: Note? = null
init {
itemView.setOnClickListener {
listener.onDeleteNote(note!!)
}
}
fun bind(note: Note) {
this.note = note
// TODO: Bindowanie wartości
}
}
I gdzieś tam, gdzie to wszystko spinasz.
val adapter = NoteAdapter(object : Listener {
override fun onDeleteNote(note: Note) = viewModel.deleteNote(note)
})
Zauważ, że korzystam z !!
w listener.onDeleteNote(note!!)
. Jest to bezpieczne, ponieważ null
na tym etapie oznacza albo błąd w Twoim kodzie albo błąd w bibliotece. Możesz opakować w requireNotNull()
, jeśli chcesz mieć ładniejszą wiadomość albo zrobić note?.let(listener::onDeleteNote)
, ale to drugie odradzam, bo można przeoczyć bugi przez tego typu korzystanie z ?
.