Définir la visibilité de la barre de progression disparue à la fin du chargement de l'image à l'aide de la bibliothèque Glide

90

Salut, je veux avoir une barre de progression pour l'image qui s'affichera lors du chargement de l'image, mais lorsque le chargement de l'image sera terminé, je veux la définir comme partie. Auparavant, j'utilisais la bibliothèque Picasso pour cela. Mais je ne sais pas comment l'utiliser avec la bibliothèque Glide. J'ai une idée qu'il existe une fonction prête pour les ressources, mais je ne sais pas comment l'utiliser. Quelqu'un peut-il m'aider?

Code pour la bibliothèque Picasso

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

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

Maintenant, comment puis-je faire cela avec Glide?

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

Je suis capable de charger l'image avec Glide, mais comment puis-je écrire progressBar.setVisibility(View.GONE);quelque part dans le code si l'image est chargée?

HariRam
la source
2
Pourquoi avez-vous changé de bibliothèque? Picasso est génial.
tasomaniac
Je recommanderais également de rester avec Picasso à moins que vous n'ayez une bonne raison de changer de bibliothèque
Chris

Réponses:

229

La question est plutôt ancienne, et je ne sais pas quelle était la situation avec le glissement à cette époque, mais maintenant cela peut être facilement fait avec l'auditeur (pas comme proposé dans la réponse choisie comme correcte).

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)
;

Vous retournez true si vous souhaitez gérer vous-même des éléments tels que des animations et false si vous souhaitez que glide les gère pour vous.

Yaroslav
la source
13
La masquer progressBaren onExceptionplus, sinon il tournera indéfiniment donnant de faux espoirs. Une fois onExceptionappelé, Glide ne fera rien d'autre que définir ce à quoi il est passé .error().
TWiStErRob
2
Cela peut entraîner une NullPointerException si vous quittez le fragment / l'activité avant le chargement de l'image.
aProperFox
1
Je ne vous agite pas pour créer des auditeurs internes, juste la façon la plus concise de montrer un outil pour accomplir la tâche.
Yaroslav
1
Bien sûr, j'ai résolu ce problème en ajoutant un appel dans onDestroyVIew () avant le super appel pour dire Glide.clear (yourImageView)
aProperFox
7
REMARQUE: .listenerdoit être appelé avant.into()
Ahmed Mostafa
31

Si vous voulez faire cela dans KOTLIN, vous pouvez essayer de cette façon:

    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)
Paulina
la source
5
Vous devez également importer Target:import com.bumptech.glide.request.target.Target
Gibolt
@Gibolt, cela m'a dérangé pendant 10 minutes d'affilée
johnrao07
17

Ma réponse était basée sur des API obsolètes. Voir ici pour la réponse la plus à jour.

Bryan Sills
la source
.listener()c'est mieux car vous recevrez plus d'informations sur votre charge (modèle, cache mémoire, ...) donc il est plus facile de décider d'une logique plus personnalisée. RequestListenerest également plus stable, le remplacement de celui Targetà créer ne vous donnera pas l'avantage de futures corrections. Vous pouvez également créer facilement un VisibilityListener<T, R>que vous pouvez réutiliser dans différents contextes.
TWiStErRob
10

Dans l'exception mettre une condition pour montrer à nouveau le 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);
Alex Zaraos
la source
7

La solution ci-dessus fonctionne plutôt bien pour moi aussi, mais lorsque j'utilise asBitmap () pour télécharger l'image. Ça ne marche pas.

Nous devons utiliser BitmapImageViewTarget

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);
            }
        });
Pratap
la source
Voir mon commentaire: stackoverflow.com/questions/26054420/… . Cette réponse est une bonne démonstration de ce que j'ai dit ici.
TWiStErRob
7

GlideDrawable est obsolète, utilisez simple 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);
Alex
la source
4

À Kotlin, vous pouvez faire comme ci-dessous

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)
Développeur Android
la source
2
  1. En XML, prenez la barre de progression avec hauteur et largeur (match_parent).
  2. Avant d'appeler la méthode de mention ci-dessous, définissez la visibilité de la barre de progression Visible.

    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
    
Vijesh Jat
la source
En quoi votre réponse est-elle différente de stackoverflow.com/a/31675796/3812404 ? De plus, le point 1 n'est pas nécessaire.
HariRam
2

Mise à jour:

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);
Narek Hayrapetyan
la source
Dites, si vous avez déjà onResourceReady, à quoi sert "into"? Ne puis-je pas simplement utiliser l'auditeur seul? Si oui, comment puis - je faire commencer le chargement sans « en?
développeur android
@android developer comme je sais que vous pouvez utiliser sans dans
Narek Hayrapetyan
il faut essayer
Narek Hayrapetyan
Mais si je n'utilise pas "into", je pense qu'il en avertit.
développeur android
1

Comment j'ai fait les choses. le plus court, un code plus propre

exemple:

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)

usage:

GlideImpl.OnCompleted {
    // completed
}

passe juste GlideImpl.OnCompleted { }au Glide.listener()

GlideImpl.kt classe qui accepte RequestListener de Glide

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

et c'est tout!

Dennis Gonzales
la source
0

Voie Kotlin

Glide.with(context)
                .load(image_url)
                .listener(object : com.bumptech.glide.request.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 {
                        img_product_banner.visibility = View.VISIBLE
                        return false
                    }

                }).placeholder(R.drawable.placeholder)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(img_product_banner)
Aditya Patil
la source
-1

C'est la meilleure réponse car elle n'utilise aucun hack comme la définition de la visibilité pour obtenir le résultat souhaité.

Téléchargez un gif de progressbargifla barre de progression et appelez-le et placez-le dans le dossier dessinable.

        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);

Une fois l'image d'url chargée, la vignette disparaît. La vignette disparaît immédiatement lorsque l'image mise en cache est chargée.

suku
la source
4
Je pense que c'est parce que cela ne répond pas à la question: OP a déjà un spinner dont il est satisfait. Cela va également à l'encontre des meilleures pratiques d'Android: l'utilisation de GIF comme spinner est si 90 et augmente considérablement la taille de l'APK; et mettre un GIF dans drawableest mauvais en soi car il n'est pas chargé par le framework, il devrait l'être rawou assetsau mieux. Il n'y a rien de mal à changer la visibilité lorsque des événements se produisent dans votre application, Android est conçu pour cela.
TWiStErRob
1
L'utilisateur verra également un espace vide pendant le décodage GIF, il est asynchrone et non immédiat. Vous mettez également en RESULTcache la barre de progression, ce qui signifie que le chargement prendra un certain temps. Les GIF doivent être SOURCEmis en cache au mieux pour plus d'efficacité; mais comme il s'agit d'un fichier local, le cache doit être NONEpour ne pas le dupliquer sur le disque, consommant encore plus d'espace utilisateur.
TWiStErRob