Carregando imagem animada em picasso


105

Eu tenho o seguinte código para carregar uma imagem no Picasso, usando um drawable para o espaço reservado para exibir enquanto a imagem está baixando. O que eu quero, no entanto, é um botão giratório animado no estilo da barra de progresso giratório que se anima enquanto a imagem está carregando, como vejo na maioria dos aplicativos profissionais. Picasso não parece suportar isso, apenas drawables de imagens estáticas. Existe uma maneira de fazer funcionar com o Picasso ou eu tenho que fazer algo diferente?

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

Respostas:


252

Como ter uma imagem de animação de progresso de carregamento usando o placeholder de Picasso:

Resolvi isso facilmente usando um objeto xml de rotação animada.

Passos:

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>

Carregando Picasso:

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

32
@DBragion funciona muito bem, mas para imagens grandes, ele escalou. podemos fixar a largura e a altura dele em um número como 32x32 pixels?
m3hdi

9
Isso não funciona, nenhuma animação é exibida. Apenas uma imagem simples
Joe Maher

4
Ele está funcionando, mas eu quero um carregador pequeno, não como meu carregador de tamanho de visualização de imagens
Ganpat Kaliya

2
Funcionou bem, a animação permanece pequena até alguns milissegundos antes que a imagem baixada apareça, ela é maximizada e esticada por alguns milissegundos, então a imagem aparece. Existe alguma solução?
tinyCoder

2
Use romannurik.github.io/AndroidAssetStudio/index.html (selecione "Launcher icon generator") para criar mdpi, hdpi, xhdpi etc.
CoolMind

73

Implementei o diálogo de progresso até o download da imagem e é muito simples. Pegue seu ImageView em layout relativo e coloque o carregador de progresso na mesma visualização de imagem. Aplique o código abaixo e controle apenas a visibilidade da caixa de diálogo de progresso.

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

                }
            });
        }

Aproveitar. :)


Obrigado .. isso me ajudou muito :)
Zohair

2
Ótimo! A melhor solução até agora, pode ser usada em muitos contextos diferentes. :)
VVZen

7
Na verdade, você deve prestar atenção às referências fracas e declarar um objeto Callback desta forma para evitar a coleta de lixo (caso contrário, onSuccess nunca poderia ser chamado):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

Qualquer pessoa confusa com o jargão, um Progress Loader é um Progress Bad
Joe Maher

2
Você esqueceu de adicionar a classe RoundedTransformation. Esta aula está disponível aqui gist.github.com/aprock/6213395
Md. Sajedul Karim

3

O Picasso não oferece suporte a marcadores de posição animados, infelizmente.

Uma maneira de contornar isso é colocar seu ImageView em um FrameLayout com o drawable animado embaixo. Dessa forma, quando o Picasso carregar a imagem, ela será carregada sobre o espaço reservado animado, dando ao usuário o efeito pretendido.

Como alternativa, você pode carregar a imagem em um destino . Então você teria a barra de progresso sendo exibida por padrão e, quando o método onBitmapLoaded fosse chamado, você poderia ocultá-lo e exibir a imagem. Você pode ver uma implementação básica disso aqui


3
O Picasso oferece suporte a marcadores de posição animados. Você escreve o arquivo drawable de animação (inclui lista de animação com vários itens que representam cada imagem na animação). Você alimenta esse arquivo para um novo objeto AnimationDrawable e, em seguida, passa-o para placeHolder () no construtor do carregador do Picasso.
Odia

1

Apenas adicione o atributo de forma na resposta do DBragion como mostrado abaixo e funcionará perfeitamente. Boa codificação.

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

Você também pode usar o Glide:

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

1

Eu encontrei a resposta para esta pergunta!

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

Além da resposta de @DBragion, tente abaixo.

Agora podemos corrigir a altura e a largura!

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

Acho que existem dois pontos principais.

  1. use noFade ()

  2. definir scaleType de image_view para "CENTER_INSIDE"


0

Eu fiz isso funcionando da seguinte maneira:

  1. Criei um drawable (encontrado em algum lugar na Internet) e coloque-o no res / drawable:

    <?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. No meu item para o GridView adicionei o elemento ProgressBar:

    <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. No adaptador adicionado Objeto de destino com os seguintes parâmetros, onde poster e spinner são referências a ImageView e ProgressBar:

    // Alvo para mostrar / ocultar ProgressBar em 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. Os resultados serão assim no carregamento - o círculo está girando (desculpe por esta captura de tela, mas as imagens estão aparecendo muito rápido): ScreenShot


0

Para quem está tentando usar a técnica do DBragion: Certifique-se de ter a versão mais recente do Picasso ou ele não girará. O meu não funcionou até que usei a versão 2.5.2.

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

6
Este deve ser um comentário sob a referida resposta
Ojonugwa Jude Ochalifu

0

Neste link , Jake Wharton disse:

Não. Usamos o Android BitmapFactory para toda a decodificação de imagens e não tem suporte para GIF animado (infelizmente).

Então você não pode


0

Basta usar Picasso PlaceHolder

  Picasso.get()
        .load(datas[position].artist?.image)
        .placeholder(R.drawable.music_image)
        .error(R.drawable.music_image)
        .into(holder.cardViewImage)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.