Codifica un'app per Android Image Gallery con Glide

Cosa starai creando

1. Che cos'è Glide?

Glide è una popolare libreria Android open source per il caricamento di immagini, video e GIF animate. Con Glide, puoi caricare e visualizzare i contenuti multimediali da molte fonti diverse, come i server remoti o il file system locale.  

Per impostazione predefinita, Glide utilizza un'implementazione personalizzata di HttpURLConnection per caricare le immagini su Internet. Tuttavia, Glide fornisce anche plugin per altre librerie di rete popolari come Volley o OkHttp. 

2. Quindi, perché usare Glide?

Sviluppare le proprie funzionalità di caricamento e visualizzazione dei media in Java può essere un vero problema: è necessario occuparsi della memorizzazione nella cache, della decodifica, della gestione delle connessioni di rete, del threading, della gestione delle eccezioni e altro ancora. Glide è una libreria facile da usare, ben pianificata, ben documentata e accuratamente testata che può farti risparmiare un sacco di tempo prezioso e risparmiarti qualche mal di testa. 

In questo tutorial, apprenderemo su Glide 3 creando una semplice applicazione per galleria di immagini. Caricherà le immagini via Internet e le visualizzerà come miniature in una RecyclerView e, quando un utente fa clic su qualsiasi immagine, aprirà un'attività di dettaglio contenente l'immagine più grande. 

3. Creare un progetto per Android Studio

Avvia il tuo Android Studio e crea un nuovo progetto con un'attività vuota chiamata Attività principale

4. Dichiarare le dipendenze

Dopo aver creato un nuovo progetto, specifica le seguenti dipendenze nel tuo build.gradle.

repositories mavenCentral () // jcenter () funziona altrettanto bene perché tira da Maven Central dipendenze // Glide compile 'com.github.bumptech.glide: glide: 3.7.0' // Recyclerview compile 'com.android. supporto: recyclerview-v7: 25.1.1 ' 

O con Maven:

 com.github.bumptech.glide planata 3.7.0   com.google.android Supporto-v4 r7 

Assicurati di sincronizzare il progetto dopo aver aggiunto la dipendenza Glide.

Librerie di integrazione

Se si desidera utilizzare una libreria di rete come OkHttp o Volley nel progetto per le operazioni di rete, si consiglia di includere l'integrazione specifica di Glide per la libreria che si sta utilizzando (anziché quella predefinita che raggruppa HttpURLConnection). 

raffica 

dependencies compile 'com.github.bumptech.glide: glide: 3.7.0' compile 'com.github.bumptech.glide: volley-integration: 1.4.0@aar' compile 'com.mcxiaoke.volley: library: 1.0. 8 '

OkHttp 

dipendenze // okhttp 3 compile 'com.github.bumptech.glide: okhttp3-integration: 1.4.0@aar' compile 'com.squareup.okhttp3: okhttp: 3.2.0' // okhttp 2 compile 'com.github. bumptech.glide: okhttp-integration: 1.4.0@aar 'compile' com.squareup.okhttp: okhttp: 2.2.0 '

È possibile visitare la guida ufficiale delle librerie di integrazione Glide per ulteriori informazioni. 

5. Aggiungi autorizzazione Internet

Poiché Glide sta per eseguire una richiesta di rete per caricare immagini tramite Internet, è necessario includere l'autorizzazione INTERNET nel nostro AndroidManifest.xml

6. Creare il layout

Inizieremo creando il nostro RecyclerView

    

Creazione del layout dell'elemento personalizzato

Quindi, creiamo il layout XML che verrà utilizzato per ciascun elemento (ImageView) all'interno del RecyclerView

   

Ora che abbiamo creato il layout, il passo successivo è creare il RecyclerView adattatore per il popolamento dei dati. Prima di farlo, creiamo il nostro semplice modello di dati. 

7. Creare un modello di dati

Definiremo un semplice modello di dati per il nostro RecyclerView. Questo modello implementa Parcelable per il trasporto di dati ad alte prestazioni da un componente all'altro. Nel nostro caso, i dati verranno trasportati da SpaceGalleryActivitySpacePhotoActivity

importa android.os.Parcel; importa android.os.Parcelable; public class SpacePhoto implementa Parcelable private String mUrl; private String mTitle; public SpacePhoto (String url, String title) mUrl = url; mTitle = titolo;  protected SpacePhoto (Parcel in) mUrl = in.readString (); mTitle = in.readString ();  Creatore finale statico pubblico CREATORE = nuovo Creatore() @Override public SpacePhoto createFromParcel (Parcel in) return new SpacePhoto (in);  @Override public SpacePhoto [] newArray (int size) return new SpacePhoto [size]; ; public String getUrl () return mUrl;  public void setUrl (String url) mUrl = url;  public String getTitle () return mTitle;  public void setTitle (String title) mTitle = title;  public static SpacePhoto [] getSpacePhotos () return new SpacePhoto [] new SpacePhoto ("http://i.imgur.com/zuG2bGQ.jpg", "Galaxy"), nuovo SpacePhoto ("http: // i. imgur.com/ovr0NAF.jpg "," Space Shuttle "), nuovo SpacePhoto (" http://i.imgur.com/n6RfJX2.jpg "," Galaxy Orion "), nuovo SpacePhoto (" http: // i. imgur.com/qpr5LR2.jpg "," Terra "), nuovo SpacePhoto (" http://i.imgur.com/pSHXfu5.jpg "," Astronauta "), nuovo SpacePhoto (" http: //i.imgur. com / 3wQcZeY.jpg "," Satellite "),;  @Override public int describeContents () return 0;  @Override public void writeToParcel (Parcel parcel, int i) parcel.writeString (mUrl); parcel.writeString (mTitle); 

8. Creare l'adattatore

Creeremo un adattatore per popolare RecyclerView con i dati. Implementeremo anche un listener di clic per aprire l'attività di dettaglio-SpacePhotoActivity-passandogli un'istanza di SpacePhoto come un extra. L'attività di dettaglio mostrerà un primo piano dell'immagine. Lo creeremo in una sezione successiva.

public class MainActivity estende AppCompatActivity // ... classe privata ImageGalleryAdapter estende RecyclerView.Adapter @Override public ImageGalleryAdapter.MyViewHolder onCreateViewHolder (ViewGroup parent, int viewType) Contesto contesto = parent.getContext (); LayoutInflater inflater = LayoutInflater.from (context); Visualizza photoView = inflater.inflate (R.layout.item_photo, parent, false); ImageGalleryAdapter.MyViewHolder viewHolder = new ImageGalleryAdapter.MyViewHolder (photoView); return viewHolder;  @Override public void onBindViewHolder (ImageGalleryAdapter.MyViewHolder holder, int position) SpacePhoto spacePhoto = mSpacePhotos [posizione]; ImageView imageView = holder.mPhotoImageView;  @Override public int getItemCount () return (mSpacePhotos.length);  public class MyViewHolder estende RecyclerView.ViewHolder implementa View.OnClickListener public ImageView mPhotoImageView; public MyViewHolder (Visualizza itemView) super (itemView); mPhotoImageView = (ImageView) itemView.findViewById (R.id.iv_photo); itemView.setOnClickListener (questo);  @Override public void onClick (Visualizza vista) int position = getAdapterPosition (); if (position! = RecyclerView.NO_POSITION) SpacePhoto spacePhoto = mSpacePhotos [posizione]; Intento intento = nuovo intento (mContext, SpacePhotoActivity.class); intent.putExtra (SpacePhotoActivity.EXTRA_SPACE_PHOTO, spacePhoto); startActivity (intento);  SpacePhoto privato [] mSpacePhotos; contesto privato mContext; public ImageGalleryAdapter (Contesto contesto, SpacePhoto [] spacePhotos) mContext = context; mSpacePhotos = spacePhotos; 

9. Caricamento di immagini da un URL

È qui che abbiamo bisogno che Glide faccia il suo lavoro, per recuperare le immagini da Internet e mostrarle all'individuo ImageViews, usando il nostro RecyclerView onBindViewHolder () metodo come l'utente fa scorrere l'app. 

// ... @Override public void onBindViewHolder (titolare MyViewHolder, posizione int) Photo photo = mPhotoList.get (posizione); ImageView imageView = holder.mPhotoImageView; Glide.with (mContext) .load (spacePhoto.getUrl ()) .placeholder (R.drawable.ic_cloud_off_red) .into (imageView);  // ... 

Passo dopo passo, ecco cosa stanno facendo le chiamate a Glide:

  • con (contesto contesto): iniziamo il processo di caricamento passando prima il nostro contesto nel con() metodo. 
  • carico (stringa di stringa): l'origine dell'immagine è specificata come percorso di directory, URI o URL.
  • segnaposto (int resourceId): un id risorsa locale dell'applicazione, preferibilmente un drawable, che sarà un segnaposto finché l'immagine non viene caricata e visualizzata.
  • in (ImageView imageView): la vista dell'immagine di destinazione in cui verrà posizionata l'immagine.

Sappi che Glide può anche caricare immagini locali. Basta passare l'ID della risorsa Android, il percorso del file o un URI come argomento per caricare() metodo. 

Ridimensionamento e trasformazione dell'immagine

È possibile ridimensionare l'immagine prima che venga visualizzata nel ImageView con Glide's .override (int width, int height) metodo. Questo è utile per creare miniature nella tua app quando si carica una dimensione di immagine diversa dal server. Si noti che le dimensioni sono in pixel non dp. 

Sono inoltre disponibili le seguenti trasformazioni di immagine:

  • fitCenter (): ridimensiona l'immagine in modo uniforme (mantenendo le proporzioni dell'immagine) in modo che l'immagine si adatti all'area specificata. L'intera immagine sarà visibile, ma potrebbe esserci un padding verticale o orizzontale.
  • centerCrop (): ridimensiona l'immagine in modo uniforme (mantenendo le proporzioni dell'immagine) in modo che l'immagine riempia l'area specificata, mostrando la maggior parte dell'immagine possibile. Se necessario, l'immagine verrà ritagliata orizzontalmente o verticalmente per adattarsi.

10. Inizializzazione dell'adattatore

Qui creiamo il nostro RecyclerView con GridLayoutManager come gestore del layout, inizializzare il nostro adattatore e collegarlo al RecyclerView

// ... @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); RecyclerView.LayoutManager layoutManager = new GridLayoutManager (this, 2); RecyclerView recyclerView = (RecyclerView) findViewById (R.id.rv_images); recyclerView.setHasFixedSize (true); recyclerView.setLayoutManager (LayoutManager); ImageGalleryAdapter adapter = new ImageGalleryAdapter (questo, SpacePhoto.getSpacePhotos ()); recyclerView.setAdapter (adattatore);  // ... 

11. Creazione dell'attività di dettaglio

Crea una nuova attività e nominala SpacePhotoActivity. Otteniamo il SpacePhoto extra e carica l'immagine con Glide come abbiamo fatto prima. Qui ci aspettiamo che il file o l'URL siano a Bitmap, quindi useremo asBitmap () per far sì che Glide riceva un Bitmap. Altrimenti il ​​carico fallirà e il .errore() la richiamata verrà attivata, causando la visualizzazione della risorsa estraibile restituita dalla richiamata dell'errore. 

Puoi anche usare asGif () se volevi assicurarti che l'immagine caricata fosse una GIF. (Spiegherò come funzionano le GIF in Glide a breve).

import android.graphics.Bitmap; import android.graphics.Color; importare android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.graphics.Palette; import android.view.ViewGroup; import android.widget.ImageView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.target.Target; public class SpacePhotoActivity estende AppCompatActivity public static final String EXTRA_SPACE_PHOTO = "SpacePhotoActivity.SPACE_PHOTO"; ImageView privato mImageView; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_photo_detail); mImageView = (ImageView) findViewById (R.id.image); SpacePhoto spacePhoto = getIntent (). GetParcelableExtra (EXTRA_SPACE_PHOTO); Glide.with (this) .load (spacePhoto.getUrl ()) .asBitmap () .error (R.drawable.ic_cloud_off_red) .diskCacheStrategy (DiskCacheStrategy.SOURCE) .into (mImageView); 

Si noti che abbiamo anche inizializzato una cache univoca per le immagini caricate: DiskCacheStrategy.SOURCE. Spiegherò di più sulla memorizzazione nella cache in una sezione successiva.

Il layout dei dettagli

Ecco un layout per visualizzare l'attività di dettaglio. Visualizza solo uno scrollable ImageView che mostrerà la versione a piena risoluzione dell'immagine caricata.

       

12. Caching in Glide

Se guardi da vicino, vedrai che quando rivedi un'immagine che è stata precedentemente caricata, carica ancora più velocemente di prima. Cosa lo ha reso più veloce? Il sistema di caching di Glide, ecco cosa.

Dopo che un'immagine è stata caricata una volta da Internet, Glide lo metterà in cache nella memoria e sul disco, salvando le richieste di rete ripetute e consentendo il recupero più rapido dell'immagine. Quindi, Glide verificherà innanzitutto se un'immagine è disponibile in memoria o sul disco prima di caricarla dalla rete. 

A seconda dell'applicazione, tuttavia, è possibile evitare la memorizzazione nella cache, ad esempio se è probabile che le immagini visualizzate cambino spesso e non vengano ricaricate.

Quindi, come si disabilita la memorizzazione nella cache? 

È possibile evitare il caching della memoria chiamando .skipMemoryCache (vero). Ma tieni presente che l'immagine verrà comunque memorizzata nella cache del disco, per evitare che anche tu usi il .diskCacheStrategy (strategia DiskCacheStrategy) metodo, che accetta uno dei seguenti valori enumerati:

  • DiskCacheStrategy.NONE: nessun dato viene salvato nella cache.
  • DiskCacheStrategy.SOURCE: dati originali salvati nella cache.
  • DiskCacheStrategy.RESULT: salva il risultato dei dati dopo le trasformazioni nella cache.
  • DiskCacheStrategy.ALL: memorizza sia i dati originali che i dati trasformati. 

Per evitare del tutto la memoria e il caching del disco, basta chiamare entrambi i metodi uno dopo l'altro:

Glide.with (this) .load (spacePhoto.getUrl ()) .asBitmap () .skipMemoryCache (true) .diskCacheStrategy (DiskCacheStrategy.NONE) .into (imageView);

13. Richiedi ascoltatori

In Glide, puoi implementare a RequestListener per monitorare lo stato della richiesta effettuata mentre l'immagine viene caricata. Verrà chiamato solo uno di questi metodi. 

  • onException (): attivato ogni volta che si verifica un'eccezione in modo da poter gestire le eccezioni in questo metodo.
  • onResourceReady (): attivato quando l'immagine viene caricata correttamente. 

Tornando alla nostra app galleria immagini, modifichiamo un po 'il display usando a RequestListener oggetto che imposterà la bitmap sul ImageView e cambia anche il colore di sfondo del layout estraendo il colore scuro e vibrato della nostra immagine utilizzando l'API della palette Android. 

// ... @Override protected void onCreate (Bundle savedInstanceState) // ... Glide.with (this) .load (spacePhoto.getUrl ()) .asBitmap () .error (R.drawable.ic_cloud_off_red) .listener (new RequestListener() @ Override pubblico booleano onException (eccezione e, modello di stringa, destinazione target, boolean isFirstResource) return false;  @Override public boolean onResourceReady (risorsa Bitmap, modello String, Target target, boolean isFromMemoryCache, boolean isFirstResource) onPalette (Palette.from (resource) .generate ()); mImageView.setImageBitmap (risorse); restituisce falso;  public void onPalette (palette palette) if (null! = palette) ViewGroup parent = (ViewGroup) mImageView.getParent (). getParent (); parent.setBackgroundColor (palette.getDarkVibrantColor (Color.GRAY)); ) .diskCacheStrategy (DiskCacheStrategy.SOURCE) .into (mImageView);  // ... 

Qui puoi anche nascondere una finestra di avanzamento se ne hai una. Con quest'ultima modifica, assicurati di includere la dipendenza Tavolozza nella tua build.gradle:

dipendenze // ... compila 'com.android.support:palette-v7:25.1.1'

14. Testare l'app

Finalmente puoi eseguire l'app! Fare clic su una miniatura per ottenere una versione completa dell'immagine.

15. Animazioni

Se esegui l'app, noterai un'animazione con dissolvenza incrociata che si verifica mentre l'immagine viene visualizzata. Glide lo ha abilitato di default, ma puoi disabilitarlo chiamando dontAnimate (), che causerà solo la visualizzazione dell'immagine senza animazione. 

Puoi anche personalizzare l'animazione del crossfade chiamando crossFade (durata int), passare la durata in millisecondi per accelerarla o rallentarla: 300 millisecondi sono l'impostazione predefinita. 

GIF animate

È molto semplice visualizzare una GIF animata nella tua app utilizzando Glide. Funziona allo stesso modo della visualizzazione di un'immagine ordinaria.

ImageView gifImageView = (ImageView) findViewById (R.id.iv_gif); Glide.with (this) .load ("http://i.imgur.com/Vth6CBz.gif") .asGif () .placeholder (R.drawable.ic_cloud_off_red) .error (R.drawable.ic_cloud_off_red) .into ( gifImageView);

Se ti aspetti che l'immagine sia una GIF, chiama asGif ()-questo assicura che Glide riceva una GIF, altrimenti il ​​caricamento fallirà e il file drawable passato al .errore() verrà mostrato invece il metodo.

Riproduzione video

Sfortunatamente, Glide non supporta il caricamento e la visualizzazione del video tramite URL. Invece può solo caricare e visualizzare i video già memorizzati sul telefono. Mostra un video passando il suo URI al caricare() metodo. 

Glide.with (context) .load (Uri.fromFile (nuovo file ("tuo / video / file / percorso")) .into (imageView) 

Conclusione

Ottimo lavoro! In questo tutorial, hai realizzato un'app completa per la galleria di immagini con Glide, e lungo la strada hai imparato come funziona la libreria e come puoi integrarla nel tuo progetto. Hai anche imparato a visualizzare sia le immagini locali e remote, come mostrare GIF animate e video, e come applicare trasformazioni di immagine come il ridimensionamento. Non solo, ma hai visto quanto sia facile abilitare la memorizzazione nella cache, la gestione degli errori e i listener di richieste personalizzate. 

Per saperne di più su Glide, puoi fare riferimento alla sua documentazione ufficiale. Per ulteriori informazioni sulla codifica per Android, consulta alcuni dei nostri altri corsi e tutorial qui su Envato Tuts+!