Android: RecyclerView

Blogger no es el lugar ideal para mostrar un tutorial largo de desarrollo, y menos aún de Android, por esta razón no me animo nunca a escribir tutoriales largos, pero bueno, voy a intentarlo a ver que tal.

RecyclerView es un tipo de vista en Android que sirve para mostrar grandes cantidades de datos que se actualizan con frecuencia en formato listado.

Es una evolución de la vista ListView mucho más flexible, cuando yo comencé en Android utilizaba ListView para este tipo de listados de datos, pero RecyclerView es más potente y más cómodo de implementar.

Los teléfonos móviles tradicionalmente han tenido muchas limitaciones de memoria por lo que en estas vistas de datos se reciclan las celdas de memoria para no caer en errores de desbordamiento, esto es común también a los iPhones. En la actualidad los móviles tienen más memoria por lo que un simple listado de datos no debería provocar desbordamientos de memoria, pero se mantiene este sistema porque optimizar siempre es bueno.

Como primer paso tienes que agregar al build.gradle del proyecto la librería de la siguiente manera:

dependencies {
    implementation 'com.android.support:recyclerview-v7:28.0.0'
}

El siguiente paso que hay que dar consiste en agregar al layout de la actividad el widget:

<?xml version="1.0" encoding="utf-8"?>
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Una vez tenemos el widget integrado en nuestro layout tenemos enlazarlo en el código para poder mostrar datos, pongo el código en java, aunque también puedes hacerlo en Kotlin.

public class MyActivity extends Activity {
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        recyclerView.setHasFixedSize(true);

        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        recyclerView.setAdapter(mAdapter);
    }
    // ...
}


En este código podemos ver como se crea el contenedor recyclerView, como se vincula con el widget agregado al layout y como lo alimentamos con datos (myDataset). Estos datos aún no están definidos.

El siguiente paso consiste en crear un layout específico para cada fila del listado. Os pongo aquí el código de un layout sencillo.

<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/item_date"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Una vez tenemos creado ese layout tenemos que vincularlo con un adapter para poder reutilizarlo en cada fila del listado.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private String[] mDataset;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView textView;
        public MyViewHolder(TextView v) {
            super(v);
            textView = v;
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        TextView v = (TextView) LayoutInflater.from(parent.getContext())
                .inflate(R.layout.my_text_view, parent, false);
        ...
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.textView.setText(mDataset[position]);

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

Una vez has implementado uno es fácil hacerlo. Espero que os sea de utilidad,

Comentarios