Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Android SDK
Code

Coder une application Image Gallery Android avec Picasso

by
Difficulty:IntermediateLength:LongLanguages:

French (Français) translation by honeymmmm (you can also view the original English article)

Final product image
What You'll Be Creating

Picasso est une bibliothèque Android open source populaire pour le chargement d'images locales et distantes. Apprenez à l'utiliser facilement pour gérer vos besoins de chargement d'images.

1. Qu'est-ce que Picasso?

Picasso (nom inspiré par le célèbre artiste français Pablo Picasso) est une bibliothèque Android open-source très populaire pour charger des images dans votre application Android. Selon les documents officiels, il est écrit:

... Picasso permet un chargement d'image sans souci dans votre application - souvent dans une seule ligne de code!

Notez que Picasso utilise OkHttp (une bibliothèque réseau du même développeur) sous le capot pour charger les images sur Internet.

2. Pourquoi utiliser Picasso?

Maintenant que vous avez appris ce qu'est Picasso, la prochaine question que vous pourriez vous poser est la suivante: pourquoi l'utiliser?

Développer vos propres fonctionnalités de chargement et d’affichage de supports en Java ou Kotlin peut être très difficile: vous devez vous occuper de la mise en cache, du décodage, de la gestion des connexions réseau, des threads, de la gestion des exceptions, etc. Picasso est une bibliothèque facile à utiliser, bien conçue, bien documentée et soigneusement testée, qui peut vous faire économiser un temps précieux et vous éviter des maux de tête.

Voici bon nombre des pièges communs de chargement d’images sur Android qui sont occupe pour vous de Picasso, selon les documents officiels :

  • gérer le recyclage d'ImageView et l'annulation de téléchargement dans un adaptateur
  • Transformations d'images complexes avec utilisation minimale de la mémoire
  • mémoire automatique et mise en cache du disque

L'ajout d'images à votre application peut donner vie à votre application Android. Donc, dans ce tutoriel, nous allons en apprendre davantage sur Picasso 2 en construisant une simple application de galerie d'images. Il chargera les images via Internet et les affichera sous forme de vignettes dans RecyclerView, et lorsqu'un utilisateur cliquera sur une image, il ouvrira une activité de détail contenant l'image plus grande.

Un exemple de projet (en Kotlin) pour ce tutoriel peut être trouvé sur notre repo GitHub pour que vous puissiez facilement suivre.

Les bons artistes copient les grands artistes volent. - Pablo Picasso

3. Prérequis

Pour pouvoir suivre ce tutoriel, vous aurez besoin de:

Lancez Android Studio et créez un nouveau projet (vous pouvez le nommer PicassoDemo) avec une activité vide appelée MainActivity. Assurez-vous de cocher également la case à cocher Include Kotlin support.

Android Studios Add an Activity to Mobile dialog

4. Déclarer les dépendances

Après avoir créé un nouveau projet, spécifiez les dépendances suivantes dans votre build.gradle. Au moment de la rédaction de ce document, la dernière version de Picasso est 2.71828.

Ou avec Maven:

Assurez-vous de synchroniser votre projet après avoir ajouté Picasso et les artefacts RecyclerView v7.

5. Ajouter une autorisation Internet

Comme Picasso va effectuer une requête réseau pour charger des images via Internet, nous devons inclure la permission INTERNET dans notre fichier AndroidManifest.xml.

Alors allez faire ça maintenant!

Notez que cela n'est nécessaire que si vous chargez des images depuis Internet. Cela n'est pas nécessaire si vous chargez uniquement des images localement sur le périphérique.

6. Créez la mise en page

Nous allons commencer par créer notre RecyclerView dans le fichier de mise en page activity_main.xml.

Création de la mise en forme d'élément personnalisée

Ensuite, créons la disposition XML (item_image.xml) qui sera utilisée pour chaque élément (ImageView) dans RecyclerView.

Maintenant que nous avons créé les dispositions requises pour notre application de galerie simple, l'étape suivante consiste à créer l'adaptateur RecyclerView pour remplir les données. Avant cela, créons notre modèle de données simple.

7. Créer un modèle de données

Nous allons définir un modèle de données simple pour notre RecyclerView. Ce modèle implémente Parcelable pour le transport de données hautes performances d'un composant à un autre sous Android. Dans notre cas, les données seront transportées de SunsetGalleryActivity vers SunsetPhotoActivity.

Notez que ce modèle SunsetPhoto ne possède qu'un seul champ appelé url (à des fins de démonstration), mais vous pouvez en avoir plus si vous le souhaitez. Cette classe implémente Parcelable, ce qui signifie que nous devons remplacer certaines méthodes.

Nous pouvons utiliser Android Studio IDEA pour générer ces méthodes pour nous, mais l'inconvénient est la maintenance. Comment? Chaque fois que nous ajoutons de nouveaux champs à cette classe, nous pouvons oublier de mettre à jour explicitement les méthodes constructor et writeToParcel, ce qui peut conduire à des bogues si nous ne mettons pas à jour les méthodes.

Maintenant, pour contourner la mise à jour ou l’écriture de ces méthodes, Kotlin 1.1.14 a introduit l’annotation@Parcelize. Cette annotation nous aidera à générer automatiquement les méthodes writeToParcel, writeFromParcel et describeContents sous le capot.

Maintenant, notre code classe SunsetPhoto est juste deux lignes! Impressionnant!

N'oubliez pas d'ajouter le code suivant à votre module d'application build.gradle:

En outre, j'ai inclus un objet compagnon (ou une méthode statique en Java) getSunsetPhotos() dans la classe de modèle SunsetPhoto qui renverra simplement une liste ArrayLite de SunsetPhoto lors de son appel.

8. Créez l'adaptateur

Nous allons créer un adaptateur pour remplir notre RecyclerView avec des données. Nous allons également implémenter un écouteur de clic pour ouvrir l'activité de détail (SunsetPhotoActivity) en lui transmettant une instance de SunsetPhoto en tant qu'intention supplémentaire. L'activité détaillée affichera un gros plan de l'image. Nous allons le créer dans une section ultérieure.

Notez que nous avons utilisé la fonction d'extension apply pour ajouter un objet à l'intention. Pour rappel, la fonction apply renvoie l'objet transmis en tant qu'argument (c'est-à-dire l'objet récepteur).

9. Chargement des images depuis une URL

Nous allons avoir besoin de Picasso pour faire son travail dans cette section, non pas pour nous peindre une œuvre d'art, mais pour aller chercher des images sur Internet et les afficher. Nous allons afficher ces images individuellement dans leurs ImageViews respectives dans notre méthode RecyclerView onBindViewHolder() lorsque l'utilisateur fait défiler l'application.

Pas à pas, voici ce que font les appels à Picasso:

La méthode get()

Cela retourne l'instance globale de Picasso (instance singleton) initialisée avec les configurations par défaut suivantes:

  • Cache mémoire LRU de 15% de la mémoire RAM disponible.
  • Cache disque de 2% d'espace de stockage jusqu'à 50 Mo mais pas moins de 5 Mo. Remarque: ceci est uniquement disponible sur API 14+.
  • Trois threads de téléchargement pour l'accès au disque et au réseau.

Notez que si ces paramètres ne répondent pas aux exigences de votre application, vous êtes libre de créer votre propre instance Picasso avec un contrôle total de ces configurations à l'aide de Picasso.Builder.

Enfin, vous appelez la méthode build () pour vous renvoyer une instance Picasso avec vos propres configurations.

Il est recommandé de le faire dans votre Application.onCreate, puis de le définir en tant qu'instance singleton avec Picasso.setSingletonInstance dans cette méthode - pour vous assurer que l'instance Picasso est globale.

La méthode load()

load(String path) lance une demande d'image en utilisant le chemin spécifié. Ce chemin peut être une URL distante, une ressource de fichier, une ressource de contenu ou une ressource Android.

  • Paceholder (int placeholderResId): identificateur de ressource de zone réservé local ou pouvant être utilisé pendant le chargement de l'image, puis affiché. Il s'agit d'une bonne expérience utilisateur pour afficher une image de substitution pendant le téléchargement de l'image.

Notez que Picasso vérifie d'abord si l'image demandée se trouve dans le cache mémoire, et si c'est le cas, elle affiche l'image à partir de là (nous aborderons plus en détail la mise en cache dans Picasso dans une section ultérieure).

Autres méthodes

  • error(int errorResId): un dessin à utiliser si l'image demandée n'a pas pu être chargée, probablement parce que le site Web est en panne.
  • noFade(): Picasso intègre toujours l'image à afficher dans ImageView. Si vous ne voulez pas cette animation en fondu, appelez simplement la méthode noFade().
  • into(ImageView imageView): la vue de l'image cible dans laquelle l'image sera placée.

Redimensionnement d'image et transformation

Si le serveur dont vous demandez l'image ne vous donne pas l'image dont vous avez besoin dans la taille requise, vous pouvez facilement redimensionner cette image à l'aide de resize(int targetWidth, int targetHeight). L'appel de cette méthode redimensionne l'image, puis l'affiche sur ImageView. Notez que les dimensions sont en pixels (px), pas dp.

Vous pouvez transmettre une ressource de dimension Android pour la largeur et la hauteur à l'aide de la méthode resizeDimen (int targetWidthResId, int targetHeightResId). Cette méthode convertit la taille de la dimension en pixels bruts, puis appelle resize() sous le capot, en passant les tailles converties (en pixels) en arguments.

Notez que ces méthodes de redimensionnement ne respecteront pas les proportions. En d'autres termes, le format de l'image peut être déformé.

Heureusement, Picasso nous fournit des méthodes utiles pour résoudre ce problème:

  • centerCrop(): ajuste l'image uniformément (en conservant le rapport hauteur / largeur de l'image) afin que l'image remplisse la zone donnée, avec autant de l'image que possible. Si nécessaire, l'image sera recadrée horizontalement ou verticalement. L'appel de cette méthode permet de recadrer une image à l'intérieur des limites spécifiées par resize().
  • centerInside(): met à l'échelle l'image de sorte que les deux dimensions soient égales ou inférieures aux limites requises. Cela va centrer une image à l'intérieur des limites spécifiées par resize().
  • onlyScaleDown(): redimensionne une image uniquement si la taille de l'image d'origine est supérieure à la taille cible spécifiée par resize().
  • fit (): essayez de redimensionner l'image pour qu'elle corresponde exactement aux limites de l'ImageView cible.

Rotation d'image

Picasso dispose d'une API simple pour faire pivoter une image et afficher cette image. La méthode rotate(float degrees) fait pivoter l'image selon les degrés spécifiés.

Dans l'exemple ci-dessus, cela ferait pivoter l'image de 90 degrés. La méthode rotate(float degrees, float pivotX, float pivotY) fait pivoter l'image selon les degrés spécifiés autour d'un point pivot.

Ici, nous allons faire pivoter l'image de 30 degrés autour du point pivot 200, 100 pixels.

Transformation

Outre la simple manipulation d'une image en la faisant pivoter, Picasso nous permet également d'appliquer une transformation personnalisée à une image avant de l'afficher.

Vous créez simplement une classe qui implémente l'interface de Transformation Picasso. Vous devez alors remplacer deux méthodes:

  • Bitmap transform(Bitmap source): cela transforme le bitmap source en un nouveau bitmap.
  • String key(): renvoie une clé unique pour la transformation, utilisée à des fins de mise en cache.

Une fois la transformation personnalisée créée, vous l'exécutez simplement en appelant transform(Transformation transformation) sur votre instance Picasso. Notez que vous pouvez également transmettre une liste de Transformation à transformer().

Ici, j'ai appliqué une transformation de recadrage en cercle à l'image de la bibliothèque Android Open Source Picasso Transformations. Cette bibliothèque comporte de nombreuses transformations que vous pouvez appliquer à une image avec Picasso, y compris des transformations pour rendre floue ou redimensionner une image. Allez le vérifier si vous souhaitez appliquer des transformations sympas à vos images.

10. Initialisation de l'adaptateur

Ici, nous créons simplement notre RecyclerView avec GridLayoutManager en tant que gestionnaire de disposition, initialisons notre adaptateur et le lions à RecyclerView.

11. Création de l'activité de détail

Créez une nouvelle activité et nommez-la SunsetPhotoActivity. Nous obtenons le supplément SunsetPhoto et nous chargeons l'image - à l'intérieur de onStart() - avec Picasso comme auparavant.

La mise en page détaillée

Voici une présentation pour afficher l'activité de détail. Il affiche simplement un ImageView qui affichera la version pleine résolution de l'image chargée.

12. Mécanisme de mise en cache dans Picasso

Si vous observez attentivement, vous remarquerez que lorsque vous revenez sur une image précédemment chargée, elle se charge encore plus rapidement qu'avant. Qu'est-ce qui l'a rendu plus rapide? C'est le mécanisme de cache de Picasso, c'est ça.

Voici ce qui se passe sous le capot. Une fois qu'une image a été chargée une fois depuis Internet, Picasso la met en cache à la fois en mémoire et sur disque, ce qui permet de sauvegarder les demandes répétées du réseau et de récupérer plus rapidement l'image. Lorsque cette image est à nouveau nécessaire, Picasso vérifie d'abord si l'image est disponible en mémoire et, si elle existe, elle la renvoie immédiatement. Si cette image n'est pas en mémoire, Picasso vérifie ensuite le disque, et si c'est le cas, il le renvoie. Si ce n'est pas là, Picasso va enfin faire une demande de réseau pour cette image et l'afficher.

En résumé, voici ce qui se passe (sous le capot) pour une demande d'image: memory -> disk -> network.

Selon votre application, cependant, vous souhaiterez peut-être éviter la mise en cache, par exemple si les images affichées risquent de changer souvent et de ne pas être rechargées.

Alors, comment désactivez-vous la mise en cache?

Vous pouvez éviter la mise en cache de la mémoire en appelant memoryPolicy (MemoryPolicy.NO_CACHE). Cela va simplement ignorer la recherche dans le cache mémoire lors du traitement d'une demande d'image.

Notez qu'il existe une autre énumération: MemoryPolicy.NO_STORE. Ceci est utile si vous êtes certain de ne demander qu'une seule image. L'application de cette méthode ne stockera pas non plus l'image dans la mémoire cache, évitant ainsi de forcer les autres images bitmap à partir de la mémoire cache.

Mais sachez que l'image sera toujours mise en cache sur le disque, pour éviter que vous utilisiezc également networkPolicy(@NonNull NetworkPolicy policy, @NonNull NetworkPolicy... additional), qui utilise une ou plusieurs des valeurs d'énumération suivantes:

  • NetworkPolicy.NO_CACHE: ignore la vérification du cache disque et force le chargement via le réseau.
  • NetworkPolicy.NO_STORE: ignore le stockage du résultat dans le cache du disque.
  • NetworkPolicy.OFFLINE: force la requête uniquement via le cache disque, ignorant le réseau.

Pour éviter la mise en cache de la mémoire et du disque, appelez les deux méthodes l'une après l'autre:

13. Demander aux auditeurs

Dans Picasso, vous pouvez implémenter un écouteur ou un rappel pour surveiller le statut de la requête que vous avez effectuée lors du chargement de l'image. Une seule de ces méthodes sera appelée si vous implémentez l'interface Target sur une requête.

  • void onBitmapFailed (e: Exception?, errorDrawable: Drawable?): déclenché chaque fois que l'image n'a pas pu être chargée avec succès. Ici, nous pouvons accéder à l'exception qui a été lancée.
  • void onBitmapLoaded(bitmap bitmap, LoadedFrom from): déclenché chaque fois qu'une image a été chargée avec succès. Ici, nous obtenons le bitmap pour montrer l'utilisateur.
  • void onPrepareLoad(DrawHolderDrawable): invoqué juste avant que votre demande soit soumise.

Ici, vous pouvez également afficher et masquer une boîte de dialogue de progression si vous en aviez une.

Il existe un autre écouteur de rappel que vous pouvez implémenter, appelé Callback. Cette interface n'a que deux méthodes: onSuccess() et onError(Exception e). Le premier est appelé lorsque le chargement de la demande d'image a réussi et le dernier est appelé en cas d'erreur lors du traitement de la demande.

Revenons à notre application galerie d'images (dans SunsetPhotoActivity), modifions un peu l'affichage en utilisant un objet Callback qui définira le bitmap sur ImageView et changera également la couleur d'arrière-plan de la mise en page en extrayant la couleur sombre et vibrante de notre image. en utilisant l'API Palette Android.

Donc, incluez l'artefact de la palette dans le build.gradle de votre module d'application:

Implémentons maintenant l'interface Callback dans notre requête Picasso.

14. Test de l'application

Enfin, vous pouvez exécuter l'application! Cliquez sur une vignette pour obtenir une version complète de l'image.

Final app result

15. Prioriser les demandes

Lorsque vous souhaitez charger différentes images en même temps sur le même écran, vous avez la possibilité de choisir laquelle est la plus importante. En d'autres termes, vous pouvez d'abord charger des images importantes.

Vous appelez simplement priority() sur votre instance de requête Picasso et transmettez l'une des énumérations suivantes: Priority.LOW, Priority.NORMAL ou Priority.HIGH.

16. Demandes de marquage

En balisant vos requêtes Picasso, vous pouvez reprendre, suspendre ou annuler des requêtes associées à des balises spécifiques. Selon votre cas d'utilisation, vous pouvez étiqueter vos demandes avec une chaîne ou des objets qui doivent définir la portée de la demande en tant que ContextActivity ou Fragment. Vous pouvez facilement marquer une requête Picasso en appelant un tag(@NonNull Object tag) sur un. Passez-lui une instance d'Object qui sert de balise.

Voici les opérations suivantes que vous pouvez effectuer sur les requêtes Picasso marquées:

  • pauseTag(Object tag): met en pause toutes les requêtes associées à la balise donnée.
  • resumeTag(Object tag): reprenez les requêtes en pause avec l'étiquette donnée.
  • cancelTag(Object tag): annule toute requête existante avec la balise donnée.

Bien que le balisage de vos requêtes vous donne un certain contrôle sur vos requêtes, vous devez faire très attention lorsque vous utilisez des balises en raison du risque de fuites de mémoire. Voici ce que dit la documentation officielle:

Picasso conservera une référence à la balise tant que cette balise est en pause et / ou a des requêtes actives. Attention aux fuites potentielles.

Chargement depuis le système de fichiers

Il est facile de charger des images localement dans votre application.

Conclusion

Bon travail! Dans ce didacticiel, vous avez créé une application de galerie d'images complète avec Picasso et, en cours de route, vous avez appris comment fonctionne la bibliothèque et comment vous pouvez l'intégrer dans votre propre projet.

Vous avez également appris à afficher des images locales et distantes, à étiqueter des requêtes, à hiérarchiser les demandes et à appliquer des transformations d'image telles que le redimensionnement. De plus, vous avez vu à quel point il est facile d'activer et de désactiver la mise en cache, la gestion des erreurs et les requêtes personnalisées.

Pour en savoir plus sur Picasso, vous pouvez vous référer à sa documentation officielle. Pour en savoir plus sur le codage pour Android, consultez quelques-uns de nos autres cours et tutoriels ici sur Envato Tuts +!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.