Imagen de carga animada en picasso


105

Tengo el siguiente código para cargar una imagen en Picasso, usando un elemento de diseño para que el marcador de posición se muestre mientras se descarga la imagen. Sin embargo, lo que quiero es una barra de progreso giratoria animada que se anima alrededor y alrededor mientras se carga la imagen, como veo en la mayoría de las aplicaciones profesionales. Picasso no parece apoyar esto, solo dibujables de imágenes estáticas. ¿Hay alguna forma de que funcione con Picasso o tengo que hacer algo diferente?

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

Respuestas:


252

Cómo tener una imagen de animación de progreso de carga usando el marcador de posición de Picasso:

Resolví esto fácilmente usando un objeto xml de rotación animada.

Pasos:

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>

Carga de Picasso:

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

32
@DBragion funciona muy bien, pero para imágenes grandes, se escaló. ¿Podemos fijar el ancho y el alto en un número como 32x32 píxeles?
m3hdi

9
Esto no funciona, no se muestra ninguna animación. Solo una imagen simple
Joe Maher

4
Está funcionando, pero quiero un cargador pequeño, no como mi cargador de tamaño de vista de imagen
Ganpat Kaliya

2
Funcionó bien, la animación permanece pequeña hasta unos milisegundos antes de que aparezca la imagen descargada, se maximiza y se estira durante unos milisegundos y luego aparece la imagen. ¿Hay alguna solución?
tinyCoder

2
Use romannurik.github.io/AndroidAssetStudio/index.html (seleccione "Generador de iconos de lanzador") para crear mdpi, hdpi, xhdpi, etc.
CoolMind

73

Implementé el diálogo de progreso hasta la descarga de la imagen y es muy simple. Tome su ImageView en un diseño relativo y coloque el cargador de progreso en la misma vista de imagen. Aplique el siguiente código y controle la visibilidad del diálogo de progreso únicamente.

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

                }
            });
        }

Disfrutar. :)


Gracias ... esto me ayudó mucho :)
Zohair

2
¡Excelente! La mejor solución hasta ahora, se puede utilizar en muchos contextos diferentes. :)
VVZen

7
En realidad, debe prestar atención a las referencias débiles y declarar un objeto de devolución de llamada de esta manera para evitar la recolección de basura (de lo contrario, nunca se podría llamar a 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);
onSuccess

Cualquiera que esté confundido por la jerga, un cargador de progreso es un progreso malo
Joe Maher

2
No pudo agregar la clase RoundedTransformation. Esta clase está aquí gist.github.com/aprock/6213395
Md. Sajedul Karim

3

Desafortunadamente, Picasso no admite marcadores de posición animados.

Una forma de evitar esto es colocar su ImageView en un FrameLayout con el dibujo animado debajo. De esta forma, cuando Picasso carga la imagen, se carga sobre la parte superior del marcador de posición animado, lo que le da al usuario el efecto deseado.

Alternativamente, puede cargar la imagen en un destino . Luego, la barra de progreso se mostrará de forma predeterminada, y cuando se llame al método onBitmapLoaded, puede ocultarlo y mostrar la imagen. Puedes ver una implementación básica de esto aquí.


3
Picasso hace de soporte animada marcadores de posición. Escribe el archivo dibujable de la animación (incluye una lista de animación con varios elementos que representan cada imagen en la animación). Alimenta ese archivo a un nuevo objeto AnimationDrawable y luego lo pasa a placeHolder () en el constructor del cargador de Picasso.
Odaym

1

Simplemente agregue el atributo de forma en la respuesta de DBragion como se muestra a continuación y funcionará a la perfección. Codificación feliz.

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

También puedes usar Glide:

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

1

¡Encontré respuesta a esta pregunta!

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

Además de la respuesta de @DBragion, intente a continuación.

¡Ahora podemos arreglar la altura y el ancho!

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

Creo que hay dos puntos clave.

  1. usar noFade ()

  2. establecer scaleType de image_view en "CENTER_INSIDE"


0

Lo hice funcionar de la siguiente manera:

  1. Creó un dibujable (que se encuentra en algún lugar de Internet) y lo puso en el res / dibujable:

    <?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. En mi artículo para el elemento ProgressBar agregado de 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. En Adapter, se agregó el objeto de destino con los siguientes parámetros, donde el póster y la ruleta son referencias a ImageView y ProgressBar:

    // Objetivo para mostrar / ocultar ProgressBar en 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. Los resultados estarán así en carga - círculo está girando (lo siento por esta captura de pantalla, pero las imágenes están apareciendo demasiado rápido): de ScreenShot


0

Para cualquiera que intente utilizar la técnica de DBragion: asegúrese de tener la última versión de Picasso o de lo contrario no funcionará. El mío no funcionó hasta que usé la versión 2.5.2.

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

6
Este debería ser un comentario debajo de dicha respuesta
Ojonugwa Jude Ochalifu

0

En este enlace , Jake Wharton dijo:

No Usamos Android BitmapFactory para toda la decodificación de imágenes y no tiene soporte GIF animado (lamentablemente).

Entonces no puedes


0

Solo usa Picasso PlaceHolder

  Picasso.get()
        .load(datas[position].artist?.image)
        .placeholder(R.drawable.music_image)
        .error(R.drawable.music_image)
        .into(holder.cardViewImage)
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.