Configure la visibilidad de la barra de progreso que se ha ido al completar la carga de la imagen usando la biblioteca Glide


90

Hola, quiero tener una barra de progreso para la imagen que se mostrará mientras se carga la imagen, pero cuando se complete la carga de la imagen, quiero configurarla para que desaparezca. Anteriormente estaba usando la biblioteca de Picasso para esto. Pero no sé cómo usarlo con la biblioteca Glide. Tengo la idea de que hay alguna función lista para recursos, pero no sé cómo usarla. ¿Alguien puede ayudarme?

Código para la biblioteca 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() {
           }
        })
;

Ahora, ¿cómo puedo hacer esto con Glide?

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

Puedo cargar la imagen con esto con Glide, pero ¿cómo puedo escribir progressBar.setVisibility(View.GONE);en algún lugar del código si la imagen se carga?


2
¿Por qué cambiaste tu biblioteca? Picasso es genial.
tasomaniac

También recomendaría seguir con Picasso a menos que tenga una buena razón para cambiar de biblioteca
Chris

Respuestas:


229

La pregunta es bastante antigua y no sé cuál era la situación con deslizamiento en esos tiempos, pero ahora se puede hacer fácilmente con el oyente (no como se propone en la respuesta elegida como correcta).

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

Devuelve verdadero si quiere manejar cosas como animaciones usted mismo y falso si quiere que glide las maneje por usted.


13
Considera esconder el progressBaren onExceptionasí, de lo contrario va a girar indefinidamente dando falsas esperanzas. Una vez que onExceptionse llame, Glide no hará nada más que configurar lo que se le pasa .error().
TWiStErRob

2
Esto puede resultar en una NullPointerException si deja el Fragmento / Actividad antes de que se cargue la imagen.
aProperFox

1
No los estoy agitando para crear oyentes de clase interna, solo la forma más concisa de mostrar una herramienta para realizar la tarea.
Yaroslav

1
Claro, resolví esto agregando una llamada en onDestroyVIew () antes de la súper llamada para decir Glide.clear (yourImageView)
aProperFox

7
NOTA: .listenerdebe ser llamado antes.into()
Ahmed Mostafa

31

Si desea hacer esto en KOTLIN, puede intentarlo de esa manera:

    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)

5
También es necesario importar Target:import com.bumptech.glide.request.target.Target
Gibolt

@Gibolt esto me molestó durante 10 minutos seguidos
johnrao07

17

Mi respuesta se basó en API obsoletas. Consulte aquí para obtener una respuesta más actualizada.


.listener()es mejor porque recibirá más información sobre su carga (modelo, memoria caché, ...) por lo que es más fácil decidir una lógica más personalizada. RequestListenertambién es más estable, anular cuál Targetcrear no le dará el beneficio de correcciones futuras. También puede crear fácilmente un VisibilityListener<T, R>archivo que puede reutilizar en diferentes contextos.
TWiStErRob

10

En excepción, ponga una condición para mostrar nuevamente el 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

La solución anterior también funciona bastante bien para mí, pero cuando uso asBitmap () para descargar la imagen. No funciona.

Necesitamos usar 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);
            }
        });

Vea mi comentario: stackoverflow.com/questions/26054420/… . Esta respuesta es una buena demostración de lo que dije allí.
TWiStErRob

7

GlideDrawable está en desuso, use Drawable simple

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

4

En Kotlin puedes hacer lo siguiente

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. En xml, tome la barra de progreso con alto y ancho (match_parent).
  2. Antes de llamar al método de mención a continuación, configure la visibilidad de la barra de progreso 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
    

¿En qué se diferencia su respuesta de la de stackoverflow.com/a/31675796/3812404 ? Además, el punto 1 no es necesario.
HariRam

2

Actualizar:

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

Diga, si ya tiene onResourceReady, ¿cuál es el uso de "into"? ¿No puedo usar al oyente solo? Si es así, ¿cómo puedo hacer que comience a cargarse sin "en"?
desarrollador de Android

@ desarrollador de Android, como sé que puede usar sin en
Narek Hayrapetyan

está para intentarlo
Narek Hayrapetyan

Pero si no uso "into", creo que advierte sobre ello.
desarrollador de Android

1

Cómo hice las cosas. el camino más corto, código más limpio

ejemplo:

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)

uso:

GlideImpl.OnCompleted {
    // completed
}

solo pasa GlideImpl.OnCompleted { }a Glide's.listener()

GlideImpl.kt clase que acepta 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
        }
    }
}

¡y eso es todo!


0

Camino de 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)

-1

Esta es la mejor respuesta, ya que no utiliza ningún truco como configurar la visibilidad para obtener el resultado deseado.

Descarga un gif de la barra de progreso y llámalo progressbargify colócalo en la carpeta dibujable.

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

Una vez que se carga la imagen de la URL, la miniatura desaparece. La miniatura desaparece inmediatamente cuando se carga la imagen en caché.


4
Creo que fue porque no responde la pregunta: OP ya tiene una ruleta con la que está contento. También va en contra de las mejores prácticas de Android: usar GIF como ruleta es tan noventa y aumenta significativamente el tamaño del APK; y poner un GIF drawablees malo en sí mismo porque no está cargado por el marco, debería estar adentro rawo assetsen el mejor de los casos. No hay nada de malo en cambiar la visibilidad cuando ocurren eventos en su aplicación, Android está diseñado para eso.
TWiStErRob

1
El usuario también verá un espacio vacío mientras se realiza la decodificación GIF, es asíncrono y no inmediato. También está RESULTalmacenando en caché la barra de progreso, lo que significa que tardará un poco en cargarse. Los GIF deben SOURCEalmacenarse en caché en el mejor de los casos para mayor eficiencia; pero dado que se trata de un archivo local, la caché debe ser NONEpara no duplicarlo en el disco, consumiendo aún más espacio de usuario.
TWiStErRob
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.