Image de chargement animée dans Picasso

105

J'ai le code suivant pour charger une image dans Picasso, en utilisant un dessinable pour que l'espace réservé s'affiche pendant le téléchargement de l'image. Ce que je veux cependant, c'est un spinner de style barre de progression en rotation animé qui s'anime autour et autour pendant le chargement de l'image, comme je le vois dans la plupart des applications professionnelles. Picasso ne semble pas prendre en charge cela, uniquement des dessins d'images statiques. Existe-t-il un moyen de le faire fonctionner avec Picasso ou dois-je faire quelque chose de différent?

Picasso.with(context).load(url)             
                    .placeholder(R.drawable.loading)
                    .error(R.drawable.image_download_error)
                    .into(view);
NZJames
la source

Réponses:

252

Comment avoir une image d'animation de progression de chargement à l'aide de l'espace réservé Picasso:

J'ai résolu ce problème facilement en utilisant un objet XML à rotation animée.

Pas:

progress_image.png

progress_image.png

/res/drawable/progress_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:gravity="center">
    <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/progress_image"
        android:pivotX="50%"
        android:pivotY="50%" />
    </item>
</layer-list>

Chargement Picasso:

Picasso.with( context )
        .load( your_path )
        .error( R.drawable.ic_error )
        .placeholder( R.drawable.progress_animation )
        .into( image_view );
DBragion
la source
32
@DBragion ça marche très bien mais pour les grandes images, ça grince. pouvons-nous en fixer la largeur et la hauteur à un nombre comme 32x32 pixels?
m3hdi
9
Cela ne fonctionne pas, aucune animation n'est affichée. Juste une image ordinaire
Joe Maher
4
Cela fonctionne mais je veux un petit chargeur pas comme mon chargeur de taille d'imageview
Ganpat Kaliya
2
A bien fonctionné, l'animation reste petite jusqu'à quelques millisecondes avant que l'image téléchargée n'apparaisse, elle est maximisée et étirée pendant quelques millisecondes, puis l'image apparaît. y-a-t'il une solution?
tinyCoder
2
Utilisez romannurik.github.io/AndroidAssetStudio/index.html (sélectionnez "Générateur d'icônes du lanceur") pour créer mdpi, hdpi, xhdpi, etc.
CoolMind
73

J'ai implémenté la boîte de dialogue de progression jusqu'au téléchargement de l'image et c'est très simple. Prenez votre ImageView dans une disposition relative et placez le chargeur de progression sur la même vue d'image. Appliquez le code ci-dessous et gérez uniquement la visibilité de la boîte de dialogue de progression.

holder.loader.setVisibility(View.VISIBLE);
            holder.imageView.setVisibility(View.VISIBLE);
         final ProgressBar progressView = holder.loader;
            Picasso.with(context)
            .load(image_url)
            .transform(new RoundedTransformation(15, 0))
            .fit()
            .into(holder.imageView, new Callback() {
                @Override
                public void onSuccess() {
                    progressView.setVisibility(View.GONE);
                }

                @Override
                public void onError() {
                    // TODO Auto-generated method stub

                }
            });
        }

Prendre plaisir. :)

Akanksha Rathore
la source
Merci ... cela m'a beaucoup aidé :)
Zohair
2
Génial! La meilleure solution à ce jour peut être utilisée dans de nombreux contextes différents. :)
VVZen
7
En fait, vous devez faire attention aux références faibles et déclarer un objet Callback de cette manière afin d'éviter le garbage collection (sinon onSuccess ne pourrait jamais être appelé):final Callback loadedCallback = new Callback() { @Override public void onSuccess() { // your code } @Override public void onError() { // your code } }; imageView.setTag(loadedCallback); Picasso.with(context).load(url).into(imageView, loadedCallback);
VVZen
Quiconque est confus par le jargon, un chargeur de progrès est un progrès mauvais
Joe Maher
2
Vous avez manqué d'ajouter la classe RoundedTransformation. Cette classe est ici gist.github.com/aprock/6213395
Md. Sajedul Karim
3

Picasso ne prend malheureusement pas en charge les espaces réservés animés.

Une façon de contourner ce problème consiste à placer votre ImageView dans un FrameLayout avec le dessin animé en dessous. De cette façon, lorsque Picasso charge l'image, elle se chargera au-dessus de l'espace réservé animé, donnant à l'utilisateur l'effet souhaité.

Vous pouvez également charger l'image dans une cible . Ensuite, vous auriez la barre de progression affichée par défaut, et lorsque la méthode onBitmapLoaded est appelée, vous pouvez la masquer et afficher l'image. Vous pouvez voir une implémentation de base de ceci ici

Michael
la source
3
Picasso prend en charge les espaces réservés animés. Vous rédigez le fichier dessinable de l'animation (comprend la liste des animations avec plusieurs éléments représentant chaque image de l'animation). Vous alimentez ce fichier dans un nouvel objet AnimationDrawable, puis le transmettez à placeHolder () dans le constructeur du chargeur Picasso.
Odaym
1

Ajoutez simplement l'attribut de forme dans la réponse de DBragion comme ci-dessous et cela fonctionnera comme du charme. Bon codage.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>

        <shape
            android:shape="rectangle">

            <size
                android:width="200dp"
                android:height="200dp"/>

            <solid
                android:color="#00FFFFFF"/>
        </shape>
    </item>

    <item android:gravity="center">
        <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
            android:drawable="@drawable/spinner"
            android:pivotX="50%"
            android:pivotY="50%" />
    </item>
</layer-list>

Vous pouvez également utiliser Glide:

Glide.with(activity).load(url)
                    .apply(RequestOptions.centerInsideTransform())
                    .placeholder(R.drawable.progress_animation)
                    .into(imageview);
Tushar Lathiya
la source
1

J'ai trouvé réponse à cette question!

Voir: https://github.com/square/picasso/issues/427#issuecomment-266276253

En plus de la réponse de @DBragion, essayez ci-dessous.

Maintenant, nous pouvons fixer la hauteur et la largeur!

image_view.scaleType = ImageView.ScaleType.CENTER_INSIDE
picasso.load(your_path)
        .fit()
        .centerCrop()
        .noFade()
        .placeholder(R.drawable. progress_animation)
        .into(image_view)

Je pense qu'il y a deux points clés.

  1. utilisez noFade ()

  2. définir le scaleType de image_view sur "CENTER_INSIDE"

Yusuke Yonehara
la source
0

Je l'ai fait fonctionner de la manière suivante:

  1. Créé un dessinable (trouvé quelque part sur Internet) et le mettre dans le res / drawable:

    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">
    
    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="7.0">
    
        <gradient
            android:angle="0"
            android:centerColor="#007DD6"
            android:endColor="#007DD6"
            android:startColor="#007DD6"
            android:type="sweep"
            android:useLevel="false" />
    </shape>

  2. Dans mon article pour l'élément ProgressBar ajouté par GridView:

    <ProgressBar
        android:id="@+id/movie_item_spinner"
        android:layout_width="@dimen/poster_width"
        android:layout_height="@dimen/poster_height"
        android:progressDrawable="@drawable/circular_progress_bar"/>
  3. Dans l'adaptateur, un objet cible a été ajouté avec les paramètres suivants, où l'affiche et la flèche sont des références à ImageView et ProgressBar:

    // Cible pour afficher / masquer ProgressBar sur ImageView

    final Target target = new Target() {
    
            @Override
            public void onPrepareLoad(Drawable drawable) {
                poster.setBackgroundResource(R.color.white);
                spinner.setVisibility(View.VISIBLE);
            }
    
            @Override
            public void onBitmapLoaded(Bitmap photo, Picasso.LoadedFrom from) {
                poster.setBackgroundDrawable(new BitmapDrawable(photo));
                spinner.setVisibility(View.GONE);
            }
    
            @Override
            public void onBitmapFailed(Drawable drawable) {
                poster.setBackgroundResource(R.color.white);
            }
        };
  4. Les résultats seront comme ça lors du chargement - le cercle tourne (désolé pour cette capture d'écran, mais les images apparaissent trop vite): ScreenShot

Dmytro Karataiev
la source
0

Pour tous ceux qui essaient d'utiliser la technique de DBragion: assurez-vous que vous avez la dernière version de Picasso, sinon elle ne tournera pas. Le mien n'a pas fonctionné jusqu'à ce que j'utilise la version 2.5.2.

compile 'com.squareup.picasso:picasso:2.5.2'
Jesse Abruzzo
la source
6
Cela devrait être un commentaire sous ladite réponse
Ojonugwa Jude Ochalifu
0

Dans ce lien , Jake Wharton a déclaré:

Nan. Nous utilisons Android BitmapFactory pour tous les décodages d'images et il n'a pas de support GIF animé (malheureusement).

Alors tu ne peux pas

Radesh
la source
0

Utilisez simplement Picasso PlaceHolder

  Picasso.get()
        .load(datas[position].artist?.image)
        .placeholder(R.drawable.music_image)
        .error(R.drawable.music_image)
        .into(holder.cardViewImage)
Exel Staderlin
la source