ListAdapter ReciclerView AndroidX – Kotlin


ListAdapter para RecyclerView se intruducio en la versión 27.1.0 de la biblioteca de soporte.
ListAdapter usa DiffUtil para rellenar los datos con los cambios efectuados, lo ejecuta en un subproceso en segundo plano, esto ayudará a RecyclerView a animar los cambios automáticamente con menos trabajo en el hilo principal sin bloquear la interfaz de usuario.

ListAdapter se extiende de RecyclerView.Adapter y implementa 3 cosas

  • getItemCount()
  • onCreateViewHolder()
  • onBindViewHolder()

Crear un ListAdapter

Crear una clase que se extienda de ListAdapter, se le debe asignar el ViewHolder y el DiffCallback

class MyListAdapter : ListAdapter<CounterTask, MyListAdapter.MyViewHolder>(DiffCallback())

En el evento onCreateViewHolder es donde se cargará la vista de cada elemento a mostrarse dentro del RecyclerView

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    val v = LayoutInflater.from(parent.context)
        .inflate(R.layout.simple_list_item_2, parent, false)
    return MyViewHolder(v)
}

Creación del MyViewHolder

inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    private val tvText1 = itemView.findViewById(android.R.id.text1) as TextView
    private val tvText2 = itemView.findViewById(android.R.id.text2) as TextView

    fun bind(item: CounterTask) {
        tvText1.text = item.title
        tvText2.text = item.clicks.toString()
    }
}

Creación del DiffCallback, encargado de comprobar los datos viejos con los nuevos y determinar si es un cambio, añadido o se debe remover

private class DiffCallback : DiffUtil.ItemCallback<CounterTask>() {
    override fun areItemsTheSame(oldItem: CounterTask, newItem: CounterTask): Boolean {
        return oldItem.title == newItem.title
    }

    override fun areContentsTheSame(oldItem: CounterTask, newItem: CounterTask): Boolean {
        return oldItem == newItem
    }

}

Carga de datos

ListAdapter se encarga de la carga de datos con el método submitList(datos) y luego con notifyDataSetChanged() para que el RecyclerView actualice los datos

mAdapter = MyListAdapter()
mAdapter.submitList(dataSet)
mAdapter.notifyDataSetChanged()

Soporte OnItemClickListener

Para implementar que los elementos se pueden clickear añadir en el layout de cada elemento

    android:background="?attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"

En el adaptador añadir

class MyListAdapter(private val itemClickListener: OnItemClickListener) 
...
interface OnItemClickListener {
    fun onItemClick(position: Int, item: CounterTask)
    fun onItemLongClick(position: Int, item: CounterTask)
}

En la carga del ViewHolder interceptar el evento OnClick

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    holder.bind(getItem(position), itemClickListener)
}
    inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val tvText1 = itemView.findViewById(android.R.id.text1) as TextView
        private val tvText2 = itemView.findViewById(android.R.id.text2) as TextView
 
        fun bind(item: CounterTask, clickListener: OnItemClickListener) {
            tvText1.text = item.title
            tvText2.text = item.clicks.toString()
            itemView.setOnClickListener { clickListener.onItemClick(adapterPosition, item) }
            itemView.setOnLongClickListener {
                clickListener.onItemLongClick(adapterPosition, item)
                return@setOnLongClickListener false
            }
        }
    }

Y la inicialización del adapter

class ListFragment : Fragment(), MyListAdapter.OnItemClickListener {
...
mAdapter.setOnItemClickListener(this)
...
override fun onItemClick(position: Int, item: CounterTask) {
    context.toast("clicked $position " + item.name)
}
override fun onItemLongClick(position: Int, item: CounterTask) {
    context.toast("clicked $position " + item.name)
}

Recursos

https://medium.com/@trionkidnapper/recyclerview-more-animations-with-less-code-using-support-library-listadapter-62e65126acdb

Anuncio publicitario

Publicado por Codelaby

Mobile DevDesigner

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: