Animiertes Ladebild in Picasso


105

Ich habe den folgenden Code, um ein Bild in Picasso zu laden, wobei ein Zeichen verwendet wird, das der Platzhalter anzeigen kann, während das Bild heruntergeladen wird. Was ich jedoch möchte, ist ein animierter Spinner im Stil eines Fortschrittsbalkens, der sich während des Ladens des Bildes immer wieder animiert, wie ich es in den meisten professionellen Apps sehe. Picasso scheint dies nicht zu unterstützen, nur statische Bildzeichnungen. Gibt es eine Möglichkeit, es mit Picasso zum Laufen zu bringen, oder muss ich etwas anderes tun?

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

Antworten:


252

So erstellen Sie ein Animationsbild für den Ladevorgang mit dem Picasso-Platzhalter:

Ich habe dies einfach mit einem animierten XML-Objekt gelöst.

Schritte:

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>

Picasso laden:

Picasso.with( context )
        .load( your_path )
        .error( R.drawable.ic_error )
        .placeholder( R.drawable.progress_animation )
        .into( image_view );

32
@DBragion es funktioniert großartig, aber für große Bilder hat es sich verschlechtert. Können wir Breite und Höhe auf eine Zahl wie 32x32 Pixel festlegen?
m3hdi

9
Dies funktioniert nicht, es wird keine Animation angezeigt. Nur ein einfaches Bild
Joe Maher

4
Es funktioniert, aber ich möchte einen kleinen Lader nicht als meinen Lader für die Bildansicht
Ganpat Kaliya

2
Die Animation funktioniert einwandfrei und bleibt bis wenige Millisekunden vor dem Erscheinen des heruntergeladenen Bilds klein. Sie wird maximiert und einige Millisekunden lang gedehnt, bevor das Bild angezeigt wird. Gibt es eine Lösung?
tinyCoder

2
Verwenden Sie romannurik.github.io/AndroidAssetStudio/index.html (wählen Sie "Launcher- Symbolgenerator "), um mdpi, hdpi, xhdpi usw. zu erstellen.
CoolMind

73

Ich habe den Fortschrittsdialog bis zum Herunterladen des Bildes implementiert und es ist sehr einfach. Nehmen Sie Ihre ImageView in ein relatives Layout und platzieren Sie den Progress Loader in derselben Bildansicht. Wenden Sie den folgenden Code an und behandeln Sie nur die Sichtbarkeit des Fortschrittsdialogs.

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

                }
            });
        }

Genießen. :) :)


Danke .. das hat mir sehr geholfen :)
Zohair

2
Toll! Die bisher beste Lösung kann in vielen verschiedenen Kontexten verwendet werden. :)
VVZen

7
Eigentlich sollten Sie auf schwache Referenzen achten und ein Callback-Objekt auf diese Weise deklarieren, um eine Speicherbereinigung zu vermeiden (andernfalls könnte onSuccess niemals aufgerufen werden):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

Jeder, der durch den Jargon verwirrt ist, ein Progress Loader ist ein Progress Bad
Joe Maher

2
Sie haben das Hinzufügen der RoundedTransformation-Klasse verpasst. Diese Klasse ist hier gist.github.com/aprock/6213395
Md. Sajedul Karim

3

Picasso unterstützt leider keine animierten Platzhalter.

Eine Möglichkeit, dies zu umgehen, besteht darin, Ihre ImageView in einem FrameLayout mit dem animierten Zeichenelement darunter zu platzieren. Auf diese Weise wird Picasso beim Laden des Bildes über den animierten Platzhalter geladen, wodurch der Benutzer den beabsichtigten Effekt erhält.

Alternativ können Sie das Bild in ein Ziel laden . Dann wird standardmäßig der Fortschrittsbalken angezeigt. Wenn die Methode onBitmapLoaded aufgerufen wird, können Sie sie ausblenden und das Bild anzeigen. Eine grundlegende Implementierung hierzu finden Sie hier


3
Picasso hat Unterstützung animiert Platzhalter. Sie schreiben die Zeichnungsdatei für die Animation (enthält eine Animationsliste mit mehreren Elementen, die jedes Bild in der Animation darstellen). Sie geben diese Datei an ein neues AnimationDrawable-Objekt weiter und übergeben sie dann an placeHolder () im Picasso-Loader-Konstruktor.
Odaym

1

Fügen Sie einfach das Formattribut in die Antwort von DBragion ein, wie unten beschrieben, und es funktioniert wie ein Zauber. Viel Spaß beim Codieren.

<?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>

Sie können Glide auch verwenden:

Glide.with(activity).load(url)
                    .apply(RequestOptions.centerInsideTransform())
                    .placeholder(R.drawable.progress_animation)
                    .into(imageview);

1

Ich habe eine Antwort auf diese Frage gefunden!

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

Versuchen Sie es zusätzlich zur Antwort von @DBragion unten.

Jetzt können wir Höhe und Breite festlegen!

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

Ich denke, es gibt zwei wichtige Punkte.

  1. benutze noFade ()

  2. Setzen Sie den scaleType von image_view auf "CENTER_INSIDE".


0

Ich habe es so gemacht:

  1. Erstellt ein Drawable (irgendwo im Internet zu finden) und fügt es in das res / drawable ein:

    <?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. In meinem Artikel für die GridView wurde das ProgressBar-Element hinzugefügt:

    <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. In Adapter wurde ein Zielobjekt mit den folgenden Parametern hinzugefügt, wobei Poster und Drehfeld Verweise auf ImageView und ProgressBar sind:

    // Ziel, ProgressBar in ImageView ein- / auszublenden

    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. Die Ergebnisse werden beim Laden so aussehen - der Kreis dreht sich (Entschuldigung für diesen Screenshot, aber die Bilder erscheinen zu schnell): Screenshot


0

Für alle, die versuchen, die Technik von DBragion zu verwenden: Stellen Sie sicher, dass Sie die neueste Version von Picasso haben, da sie sich sonst nicht dreht. Meins hat nicht funktioniert, bis ich Version 2.5.2 verwendet habe.

compile 'com.squareup.picasso:picasso:2.5.2'

6
Dies sollte ein Kommentar unter dieser Antwort sein
Ojonugwa Jude Ochalifu

0

In diesem Link sagte Jake Wharton:

Nee. Wir verwenden die Android BitmapFactory für die gesamte Bilddecodierung und sie hat (leider) keine animierte GIF-Unterstützung.

Dann kannst du nicht


0

Verwenden Sie einfach Picasso PlaceHolder

  Picasso.get()
        .load(datas[position].artist?.image)
        .placeholder(R.drawable.music_image)
        .error(R.drawable.music_image)
        .into(holder.cardViewImage)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.