Stellen Sie die Sichtbarkeit des Fortschrittsbalkens nach Abschluss des Bildladens mithilfe der Glide-Bibliothek ein


87

Hallo, ich möchte einen Fortschrittsbalken für das Bild haben, der beim Laden des Bildes angezeigt wird, aber wenn das Laden des Bildes abgeschlossen ist, möchte ich ihn auf "weg" setzen. Früher habe ich dafür die Picasso-Bibliothek verwendet. Aber ich weiß nicht, wie ich es mit der Glide-Bibliothek verwenden soll. Ich habe die Idee, dass eine ressourcenbereite Funktion vorhanden ist, weiß aber nicht, wie ich sie verwenden soll. Kann mir jemand helfen?

Code für die Picasso-Bibliothek

Picasso.with(mcontext).load(imgLinkArray.get(position).mUrlLink)
       .into(imageView, new Callback() {
           @Override
           public void onSuccess() {
               progressBar.setVisibility(View.GONE);
           }

           @Override
           public void onError() {
           }
        })
;

Wie kann ich das mit Glide machen?

Glide.with(mcontext).load(imgLinkArray.get(position).mUrlLink)
     .into(imageView);

Ich kann das Bild mit Glide laden, aber wie kann ich progressBar.setVisibility(View.GONE);irgendwo in Code schreiben , wenn das Bild geladen wird?


2
Warum haben Sie Ihre Bibliothek geändert? Picasso ist großartig.
Tasomaniac

Ich würde auch empfehlen, bei Picasso zu bleiben, es sei denn, Sie haben guten Grund, die Bibliothek zu wechseln
Chris

Antworten:


225

Die Frage ist ziemlich alt, und ich weiß nicht, wie es damals mit dem Gleiten war, aber jetzt kann es leicht mit dem Hörer gemacht werden (nicht wie in der als richtig gewählten Antwort vorgeschlagen).

progressBar.setVisibility(View.VISIBLE);
Glide.with(getActivity())
     .load(args.getString(IMAGE_TO_SHOW))
     .listener(new RequestListener<String, GlideDrawable>() {
         @Override
         public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
             return false;
         }

         @Override
         public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
             progressBar.setVisibility(View.GONE);
             return false;
         }
     })
     .into(imageFrame)
;

Sie geben true zurück, wenn Sie Dinge wie Animationen selbst verarbeiten möchten, und false, wenn Sie möchten, dass glide sie für Sie verarbeitet.


13
Ziehen Sie progressBarin Betracht, das In auch zu verstecken onException, sonst dreht es sich auf unbestimmte Zeit und gibt falsche Hoffnung. Sobald onExceptionGlide genannt wird, wird nichts anderes getan, als festzulegen, an was übergeben wird .error().
TWiStErRob

2
Dies kann zu einer NullPointerException führen, wenn Sie das Fragment / die Aktivität verlassen, bevor das Bild geladen wird.
aProperFox

1
Ich rege Sie nicht dazu auf, Hörer der inneren Klasse zu schaffen, sondern nur die prägnanteste Art, ein Werkzeug zur Erfüllung der Aufgabe zu zeigen.
Jaroslaw

1
Sicher, ich habe dieses Problem gelöst, indem ich vor dem Superaufruf einen Aufruf in onDestroyVIew () hinzugefügt habe, um Glide.clear (yourImageView)
aProperFox

7
HINWEIS: .listenermuss vorher angerufen werden.into()
Ahmed Mostafa

29

Wenn Sie dies in KOTLIN tun möchten, können Sie Folgendes versuchen:

    Glide.with(context)
            .load(url)
            .listener(object : RequestListener<Drawable> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
                    //TODO: something on exception
                }
                override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    Log.d(TAG, "OnResourceReady")
                    //do something when picture already loaded
                    return false
                }
            })
            .into(imgView)

4
Außerdem muss Ziel importiert werden:import com.bumptech.glide.request.target.Target
Gibolt

17

Meine Antwort basierte auf veralteten APIs. Sehen Sie hier für die mehr up-to-date Antwort.


.listener()ist besser, weil Sie mehr Informationen über Ihre Last erhalten (Modell, Speichercache, ...), sodass es einfacher ist, mehr benutzerdefinierte Logik zu bestimmen. RequestListenerist auch stabiler. Wenn TargetSie überschreiben, was erstellt werden soll, profitieren Sie nicht von zukünftigen Korrekturen. Sie können auch einfach eine erstellen VisibilityListener<T, R>, die Sie in verschiedenen Kontexten wiederverwenden können.
TWiStErRob

9

In Ausnahme setzen Sie eine Bedingung für die erneute Anzeige der ProgressBar

 Glide.with(context)
    .load(image_url)
    .listener(new RequestListener<String, GlideDrawable>() {
        @Override
        public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
            if(e instanceof UnknownHostException)
                progressBar.setVisibility(View.VISIBLE);
            return false;
        }

        @Override
        public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
            progressBar.setVisibility(View.GONE);
            return false;
        }
    })
    .into(imageView);

7

Die obige Lösung funktioniert auch für mich ziemlich gut, aber wenn ich asBitmap () verwende , um das Bild herunterzuladen. Es funktioniert nicht.

Wir müssen BitmapImageViewTarget verwenden

Glide.with(this) .load(imageURL)
 .asBitmap()
 .placeholder(R.drawable.bg)
 .into(new BitmapImageViewTarget(imageView) {
            @Override
            public void onResourceReady(Bitmap  drawable, GlideAnimation anim) {
                super.onResourceReady(drawable, anim);
                progressBar.setVisibility(View.GONE);
            }
        });

Siehe meinen Kommentar: stackoverflow.com/questions/26054420/… . Diese Antwort ist eine gute Demonstration dessen, was ich dort gesagt habe.
TWiStErRob

6

GlideDrawable sind veraltet, verwenden Sie einfach Drawable

RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.placeholder);
requestOptions.error(R.drawable.error);

Glide.with(getContext())
                 .setDefaultRequestOptions(requestOptions)
                 .load(finalPathOrUrl)
                 .listener(new RequestListener<Drawable>() {
                        @Override
                        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                            progressBar.setVisibility(View.GONE);
                            return false;
                        }

                        @Override
                        public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                            progressBar.setVisibility(View.GONE);
                            return false;
                        }
                    })
                 .into(mImageView);

3

In Kotlin können Sie wie unten tun

Glide.with(context)
            .setDefaultRequestOptions(RequestOptions().placeholder(R.drawable.ic_image_placeholder).error(R.drawable.ic_image_placeholder))
            .load(url)
            .listener(object : RequestListener<Drawable>{
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
                    return false
                }

                override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    return false
                }

            })
            .into(imageView)

2
  1. In XML nehmen Sie den Fortschrittsbalken mit Höhe und Breite (match_parent).
  2. Stellen Sie vor dem Aufrufen der unten genannten Methode die Sichtbarkeit des Fortschrittsbalkens sichtbar ein.

    public void setImageWIthProgressBar(Context context, final ImageView imageView, String imageUrl, final ProgressBar progressBar) {
    
            Glide.with(context)
                    .load(imageUrl)
                    .listener(new RequestListener<String, GlideDrawable>() {
                        @Override
                        public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                            progressBar.setVisibility(View.GONE);
                            return false;
                        }
    
                        @Override
                        public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                            progressBar.setVisibility(View.GONE);
                            return false;
                        }
                    })
                    .into(imageView);
    
        }//setImageWIthProgressBar

Wie unterscheidet sich Ihre Antwort von stackoverflow.com/a/31675796/3812404 ? Auch Punkt 1 wird nicht benötigt.
HariRam

2

Aktualisieren:

Glide.with(this)
            .load(imageUrl)
            .listener(new RequestListener<Drawable>() {
                @Override
                public boolean onLoadFailed(@Nullable final GlideException e,
                                            final Object model, final Target<Drawable> target,
                                            final boolean isFirstResource) {
                    showProgress(false);

                    mNoContentTextView.setVisibility(View.VISIBLE);

                    return false;
                }

                @Override
                public boolean onResourceReady(final Drawable resource, 
                                               final Object model, 
                                               final Target<Drawable> target, 
                                               final DataSource dataSource, 
                                               final boolean isFirstResource) {
                    showProgress(false);

                    mNoContentTextView.setVisibility(View.GONE);
                    mContentImageView.setImageDrawable(resource);

                    return false;
                }
            })
            .into(mContentImageView);

Wenn Sie bereits onResourceReady haben, was nützt "into"? Kann ich den Hörer nicht einfach alleine benutzen? Wenn ja, wie kann ich dafür sorgen, dass es ohne "in" geladen wird?
Android-Entwickler

@ Android Entwickler, wie ich weiß, können Sie ohne in
Narek Hayrapetyan

es steht zu versuchen
Narek Hayrapetyan

Aber wenn ich nicht "in" verwende, warnt ich davor.
Android-Entwickler

1

Wie ich Dinge gemacht habe. der kürzere Weg, sauberer Code

Beispiel:

progress_bar.visibility = View.VISIBLE

profilePicturePath?.let {
    GlideApp.with(applicationContext)
        .load(CloudStorage.pathToReference(it))
        .placeholder(R.drawable.placeholder)
        .listener(GlideImpl.OnCompleted {
            progress_bar.visibility = View.GONE
        })
    .into(profile_picture)
} ?: profile_picture.setImageResource(R.drawable.placeholder)

Verwendung:

GlideImpl.OnCompleted {
    // completed
}

GlideImpl.OnCompleted { }geh einfach zum Glide's.listener()

GlideImpl.kt-Klasse, die den RequestListener von Glide akzeptiert

import android.graphics.drawable.Drawable
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target

object GlideImpl {

    object OnCompleted : RequestListener<Drawable> {

        private lateinit var onComplete: () -> Unit

        operator fun invoke(onComplete: () -> Unit): OnCompleted {
            OnCompleted.onComplete = { onComplete() }
            return this
        }

        override fun onResourceReady(
            resource: Drawable?,
            model: Any?,
            target: Target<Drawable>?,
            dataSource: DataSource?,
            isFirstResource: Boolean
        ): Boolean {
            onComplete()
            return false
        }

        override fun onLoadFailed(
            e: GlideException?,
            model: Any?,
            target: Target<Drawable>?,
            isFirstResource: Boolean
        ): Boolean {
            onComplete()
            return false
        }
    }
}

und das ist alles!


-1

Dies ist die beste Antwort, da kein Hack wie das Einstellen der Sichtbarkeit verwendet wird, um die gewünschte Ausgabe zu erhalten.

Laden Sie ein GIF der Fortschrittsanzeige herunter, rufen Sie es auf progressbargifund legen Sie es in den Zeichenordner.

        Glide.with(ctx)
            .load(url)
            .thumbnail(Glide.with(ctx).load(R.drawable.progressbargif))
            .diskCacheStrategy(DiskCacheStrategy.SOURCE)
            .error(R.drawable.image_unavailable)
            .crossFade(200)
            .into(iv);

Sobald das URL-Bild geladen ist, verschwindet die Miniaturansicht. Die Miniaturansicht verschwindet sofort, wenn das zwischengespeicherte Bild geladen wird.


4
Ich denke, das lag daran, dass die Frage nicht beantwortet wird: OP hat bereits einen Spinner, mit dem er zufrieden ist. Es ist auch gegen Android Best Practices: Die Verwendung von GIF als Spinner ist so 90er Jahre und erhöht die APK-Größe erheblich; und das Einfügen eines GIF drawableist an sich schlecht, da es nicht vom Framework geladen wird, sondern in rawoder assetsbestenfalls sein sollte. Es ist nichts Falsches daran, die Sichtbarkeit zu ändern, wenn Ereignisse in Ihrer App auftreten. Android ist dafür konzipiert.
TWiStErRob

1
Der Benutzer sieht auch einen leeren Bereich, während die GIF-Dekodierung stattfindet. Sie ist asynchron und nicht unmittelbar. Sie RESULTspeichern auch den Fortschrittsbalken, was bedeutet, dass das Laden eine Weile dauert. GIFs sollten SOURCEaus Effizienzgründen bestenfalls zwischengespeichert werden. Da es sich jedoch um eine lokale Datei handelt, muss der Cache so gestaltet sein, dass NONEsie nicht auf der Festplatte dupliziert wird, wodurch noch mehr Benutzerplatz belegt wird.
TWiStErRob
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.