Una de las principales acciones a la hora de trabajar con un conjunto de datos es la de mostrarlos en una lista. Para ello en los elementos vistos en entradas anteriores (listview, recyclerview, etc.) se utilizaban adaptadores como BaseAdapter que permiten renderizar los datos con el aspecto deseado. Cuando los datos provienen de Firebase y se quieren renderizar en un elemento como recyclerview se puede utilizar uno de los adaptadores anteriores o uno particular para firebase.

Firebaseui

Firebaseui es una libreria que permite trabajar determinados aspectos de firebase de forma sencilla. Uno de estos elementos es la asociación de datos con listas. Lo primero que se debe hacer es importar la librería en el gradle. En este ejemplo también se utilizará la libreria Picasso y RecyclerView por lo que se deberá incluir también su implementación:

implementation 'com.firebaseui:firebase-ui:0.4.4'
implementation 'com.android.support:recyclerview-v7:26.0.0-alpha1'
implementation 'com.squareup.picasso:picasso:2.5.2'

Esta libreria permite utilizar un adaptador que asocia a un elemento lista. Para ello se necesita lo siguiente

El ejemplo que se ejecutará a continuación junto con la base de datos utilizada es el siguiente

[ezcol_1half][/ezcol_1half] [ezcol_1half_end][/ezcol_1half_end]

Clase modelo

Representa el objeto que se traerá de base de datos firebase. En el ejemplo se utiliza un lenguaje de programación con logo, nombre, sistema y versión

public class Lenguaje {

    String logo, nombre, sistema;
    int version;

    public Lenguaje() {
    }

    public Lenguaje(String logo, String nombre, String sistema, int version) {
        this.logo = logo;
        this.nombre = nombre;
        this.sistema = sistema;
        this.version = version;
    }

    public String getLogo() {
        return logo;
    }

    public String getNombre() {
        return nombre;
    }

    public String getSistema() {
        return sistema;
    }

    public int getVersion() {
        return version;
    }

    @Override
    public String toString() {
        return "Lenguaje{" +
                "logo='" + logo + '\'' +
                ", nombre='" + nombre + '\'' +
                ", sistema='" + sistema + '\'' +
                ", version=" + version +
                '}';
    }
}

Clase Holder

Representa el elemento que se renderizará en el elemento de lista. Extentiende de RecyclerView.ViewHolder y como mínimo en constructor tendrá como parámetro el layout que se utilizará. Adicionalmente se pasará como parámetro cualquier cosa que sea necesaria. En este constructor se inicializarán todos los elementos del layout

public class LenguajeHolder extends RecyclerView.ViewHolder {

    ImageView imagen;
    TextView nombre,sistema;

    public LenguajeHolder(View itemView) {
        super(itemView);
        imagen = itemView.findViewById(R.id.imagenHolder);
        nombre = itemView.findViewById(R.id.nombreHolder);
        sistema = itemView.findViewById(R.id.sistemaHolder);
    }
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_gravity="center">

    <ImageView
        android:id="@+id/imagenHolder"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:src="@mipmap/ic_launcher"/>

    <LinearLayout
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        android:padding="10dp">

        <TextView
            android:id="@+id/nombreHolder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
            android:text="Ejemplo"
            android:paddingBottom="10dp"/>

        <TextView
            android:id="@+id/sistemaHolder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Ejemplo"/>

    </LinearLayout>

</LinearLayout>

Clase adaptador

Representa el punto de unión entre firebase y el elemento lista. Extiende de FirebaseRecyclerAdapter y como elementos necesarios se pasa la clase del objeto se se podrá en los ítems y la clase que representa el holder (las dos clases creadas anteriormente). Además el constructor deberá tener como mínimo:

  • Class<> modelClass: la clase del elemento que se representará en cada ítem de la lista
  • int modelLayout: el layout que se utilizará para representar los elementos
  • Class<> viewHolderClass: la clase que se utilizar para asociar la parte gráfica con la lista
  • DatabaseReference ref: la referencia de la base de datos desde donde provienen los datos- Opcionalmente se podrá pasar un objeto de tipo Query  con los datos en vez de la referencia a la base de datos.

Adicionalmente se podrán pasar por parámetros todas aquellas cosas necesarias. Con la extensión se obliga a utilizar el método populateViewHolder que se encarga de pintar todos los elementos de la base de datos. Este método tiene como parámetros viewHolder, model y position.

class AdaptadorFirebase extends FirebaseRecyclerAdapter<Lenguaje, LenguajeHolder> {

    Context context;

    public AdaptadorFirebase(Class<Lenguaje> modelClass, int modelLayout, Class<LenguajeHolder> viewHolderClass, DatabaseReference ref, Context c)
    {
        super(modelClass, modelLayout, viewHolderClass, ref);
        context = c;
    }

    @Override
    protected void populateViewHolder(LenguajeHolder viewHolder, final Lenguaje model, int position) {
        viewHolder.nombre.setText(model.getNombre());
        viewHolder.sistema.setText(model.getSistema());
        Picasso.with(context).load(model.getLogo()).into(viewHolder.imagen);
        viewHolder.nombre.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context,"La version es: "+ String.valueOf(model.getVersion()),Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Clase Activity

Por ultimo la clase que representa la activity. En esta clase es reseñable la creación del adaptador mediante la clase anterior, donde se le pasan los datos que se piden en constructor:

public class MainActivity extends AppCompatActivity {

    RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.recycler);

        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference referencia = database.getReference("Lenguajes");
        

        AdaptadorFirebase adaptadorFirebase = new AdaptadorFirebase(Lenguaje.class,R.layout.item_recycler
                ,LenguajeHolder.class,referencia,MainActivity.this);

        recyclerView.setAdapter(adaptadorFirebase);
        recyclerView.setLayoutManager(new GridLayoutManager(MainActivity.this,2,
                LinearLayoutManager.VERTICAL,false));
    }
}