Il problema
Nell'esempio della sezione precedente le immagini utilizzate nel recycler view sono contenute nell'app tra le risorse drawable. Molto spesso ci si trova a dover visualizzare liste con immagini provenienti da fonti esterne alle risorse dell'app. Immagini provenienti dal Web o dal file system sono i tipici esempi.
Quando si carica un'immagine bisogna sempre tenere in considerazione che il tempo di recupero dello stessa può essere significativo. Al fine di evitare vistosi rallentamenti nell'interfaccia utente, soprattutto quando si utilizza le connessioni di rete per recuperare le risorse, è bene effettuare queste operazioni su un altro thread (le connessioni di rete sul thread principale sono normalmente vietate, proprio per questo motivo).
Gestire in modo asincrono il caricamento delle immagini può essere un task di difficile gestione e un facile generatore di bug.
Glide: caricamento delle immagini
Glide è una libreria open source scritta in Java per piattaforma Android che si occupa di una sola cosa: caricare
immagini in modo efficiente. Per illustrare il suo funzionamento prenderemo l'esempio della sezione precedente in cui si utilizzava un
recycler view per visualizzare un elenco di contatti e lo arricchiremo
con delle immagini prese dal sito Loremflickr.
Per utilizzare Glide all'interno di un progetto e includere la libreria dovremo operare nel seguente modo:
dependencies {
// ..
compile 'com.github.bumptech.glide:glide:4.3.0'
// ..
}
Nel manifest
dell'applicazione deve essere presente il permesso di utilizzare la connessione ad
Internet.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.html.android.libraries.myapplication2">
<uses-permission android:name="android.permission.INTERNET" />
..
Per caricare contenuti
nelle image view utilizzate all'interno del recycler view è sufficiente modificare il codice del recycler view
adapter nel seguente modo:
public class ContactAdapter extends AbstractRecyclerViewAdapter<Contact, ContactAdapter.ViewHolder> {
// ..
@Override
public void onBindItem(final ViewHolder holder, final Contact item) {
holder.phone = item;
Glide
.with(this.context)
.load("https://loremflickr.com/240/240/?i=" + System.currentTimeMillis())
.into(holder.imageView);
holder.tvTxtPhoneName.setText(item.contactName);
holder.tvTxtPhoneNumber.setText(item.number);
holder.tvTxtPhoneNumber.setVisibility(View.VISIBLE);
holder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ContactAdapter.this.context, "Selezionato " + holder.phone.contactName, Toast.LENGTH_LONG)
.show();
}
});
}
Il codice che consente di caricare le immagini in modo asincrono per poi visualizzarlo nell'image view denominata imageView
è in
particolare:
Glide
.with(this.context)
.load("https://loremflickr.com/240/240/?i=" + System.currentTimeMillis())
.into(holder.imageView);
Con il codice sopra riportato abbiamo la possibilità di caricare le immagini in modo asincrono. E se volessimo
personalizzare il caricamento delle immagini? Glide consente di
fare ciò mediante un oggetto di tipo RequestOptions
. Nel nostro
caso vogliamo inserire un place holder (la risorsa ic_contact_phone_black_24dp
) in attesa del
caricamento e
trasformare l'immagine caricata in un cerchio. Per fare questo, è sufficiente modificare il codice precedente in:
RequestOptions myOptions = new RequestOptions()
.placeholder(R.drawable.ic_contact_phone_black_24dp)
.circleCrop();
Glide
.with(this.context)
.load("https://loremflickr.com/240/240/?i=" + System.currentTimeMillis())
.apply(myOptions)
.into(holder.imageView);
Il risultato ottenuto è simile a quanto riportato nell'immagine:.
Eseguendo l'applicazione in allegato a noterete che l'elenco dei contatti
viene caricato immediatamente, mentre le immagini vengono visualizzate in modo asincrono senza bloccare la UI
dell'applicazione.
Glide è disponibile come progetto open source su GitHub. La documentazione ufficiale è invece disponibile qui.