El componente RecyclerView ha sido una de los componente más importante de Android y de los que más uso tiene en la mayoría de las aplicaciones.
Es muy importante saber como usarlo y como configurar su comportamiento. Eso es lo que veremos en este tutorial.
El componente RecyclerView fue añadido por Google a partir de la versión Lolipop. Este componente aumenta enormemente el rendimiento frente al clásico ListView.
En este tutorial veremos:
- Como usar el componente RecyclerView en un layout personalizado.
- Usar los eventos
- Personalizar la apariencia del RecyclerView.
Primeros pasos con Android RecyclerView
Android RecyclerView usa un adapter para representar la información que mostraremos en una lista, este concepto ya lo usaba ListView, pero va un paso más allá e incrementa enormemente el rendimiento.
El adapter es una clase que hereda de RecyclerView.Adapter que se abstrae de la UI y de los datos que queremos representar. Debido a esto debemos personalizarlo para poder usar los datos que queremos mostrar.
Para empezar a usar RecyclerView debemos importar la librería correspondiente mediante Gradle.
dependencies { .... compile 'com.android.support:RecyclerView-v7:25.3.1' }
Ahora ya tenemos el proyecto preparado para usar RecyclerView en nuestra UI. Para facilitar las cosas usaremos como datos maestros una clase que representa un contacto y su fecha de nacimiento.
public class Contacts { private String name; private Date birthday; public Contacts(String name, Date birthday) { this.name = name; this.birthday = birthday; } }
Lo próximo que debemos hacer es crear el fichero de layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="vertical"/> </LinearLayout>
Obtendremos la referencia en nuestra clase de la forma clásica:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view); }
En este paso es cuando tenemos que implementar nuestro adapter:
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.MyViewHolder> { private List<Contacts> contactsList; private DateFormat df = new SimpleDateFormat("dd/MM/yyyy"); /** * View holder class * */ public class MyViewHolder extends RecyclerView.ViewHolder { public TextView countryText; public TextView popText; public MyViewHolder(View view) { super(view); countryText = (TextView) view.findViewById(R.id.contactName); popText = (TextView) view.findViewById(R.id.birthday); } } public ContactsAdapter(List<Contacts> contactLists) { this.contactsList = contactLists; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { Contacts c = contactsList.get(position); holder.countryText.setText(c.name); holder.popText.setText(df.format(c.birthday)); } @Override public int getItemCount() { return contactsList.size(); } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.row,parent, false); return new MyViewHolder(v); } }
Hay algunos métodos que es muy importante que sobreescribamos para personalizar el comportamiento del RecyclerView. Lo primero de todo es crear una clase simple (MyViewHolder) encargada de almacenar las referencias a los componentes gráficos de las filas.
Lo siguiente que debemos hacer es el método onCreateViewHolder, en él rellenaremos el layout devolviendo una instancia de la clase MyViewHolder. En este ejemplo el layout de la fila es el siguiente:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/contactName" android:textStyle="bold" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/birthday"/> </LinearLayout>
Por último sobreescriberemos el método onBindViewHolder, encargado de enlazar nuestro UI con los datos. Este método simplemente obtiene los datos de un ArrayList, y en función de la posición actual almacena estos valores en MyViewHolder.
Para inicializar el adapter con nuestros datos haremos lo siguiente:
ContactsAdapter ca = new ContactsAdapter(contactsList); rv.setAdapter(ca);
No debemos olvidar establecer el Layout Manager
LinearLayoutManager llm = new LinearLayoutManager(this); llm.setOrientation(LinearLayoutManager.VERTICAL); rv.setLayoutManager(llm);
Item click listener
Lo primero que debemos hacer para implementar el click para los items de un RecyclewView es crear un listener que se encargue de controlar este comportamiento en el adapter:
public interface OnItemClickListener { void onItemClick(Contacts item); }
Habrá que modificar el constructor del adapater para que acepte como parámetro un objeto que implemente este listener.
private final OnItemClickListener listener; public ContactsAdapter(List<Contacts> contactLists,OnItemClickListener listener) { this.contactsList = contactLists; this.listener = listener; }
Luego en el método onBindViewHolder deberemos asignarle el listener a cada item:
@Override public void onBindViewHolder(MyViewHolder holder, final int position) { final Contacts c = contactsList.get(position); holder.contactText.setText(c.name); holder.birthdayText.setText(df.format(c.birthday)); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onItemClick(c); } }); }
Por último, cuando declaremos el adapter en nuestro Activity debemos pasarle como parámetro el listener correspondiente para controlar el click.
rv.setAdapter(new ContactsAdapter(contactsList, new ContactsAdapter.OnItemClickListener() { @Override public void onItemClick(Contacts item) { Toast.makeText(MainActivity.this, "Item Clicked", Toast.LENGTH_LONG).show(); } }));
Con esto ya tenemos listo nuestro RecyclerView con ItemClick.
Puedes ver el código completo en el siguiente enlace: https://github.com/jamontes79/RecyclerViewExample
Sin duda, esto es una primera toma de contacto con este potente control. En posteriores artículos podríamos profundizar más en él.
¿Tienes alguna duda al respecto? ¿Sobre qué aspectos de este control te gustaría que habláramos?
Hola Alberto, gracias por el tutorial, muy completo.
Tengo una duda, cuando no hay datos la app se cierra y me muestra error en esta parte:
@Override
public int getItemCount() {
return contactsList.size();
}
Sabes como lo puedo solucionar?
Hola Juan, muchas gracias por tu comentario.
Respecto a tu comentario, ¿puede ser que no esté inicializado el vector contactsList?
Posiblemente si en la linea donde se declara la cambias por la siguiente se solucione el problema:
private List contactsList = new List ();
Un saludo
Bien explicado y preciso.
Gracias por el tutorial.