Анимированная загрузка изображения в пикассо

105

У меня есть следующий код для загрузки изображения в Picasso, используя вытяжку для отображения заполнителя во время загрузки изображения. Однако мне нужен анимированный спиннер в стиле вращающейся шкалы прогресса, который анимируется вокруг и вокруг во время загрузки изображения, как я вижу в большинстве профессиональных приложений. Пикассо, похоже, не поддерживает это, только статические изображения. Есть ли способ заставить его работать с Пикассо или мне нужно сделать что-то другое?

Picasso.with(context).load(url)             
                    .placeholder(R.drawable.loading)
                    .error(R.drawable.image_download_error)
                    .into(view);
NZJames
источник

Ответы:

252

Как получить изображение анимации загрузки с помощью заполнителя Picasso:

Я легко решил это, используя объект xml с анимированным вращением.

Шаги:

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>

Загрузка Пикассо:

Picasso.with( context )
        .load( your_path )
        .error( R.drawable.ic_error )
        .placeholder( R.drawable.progress_animation )
        .into( image_view );
DBragion
источник
32
@DBragion отлично работает, но для больших изображений он увеличен. можем ли мы установить его ширину и высоту до 32x32 пикселей?
m3hdi
9
Это не работает, анимация не отображается. Просто простое изображение
Джо Махер
4
Он работает, но мне нужен небольшой загрузчик, а не мой загрузчик размера изображения
Ганпат Калия
2
Работает нормально, анимация остается маленькой до тех пор, пока не появится загруженное изображение за несколько миллисекунд, после чего изображение развернется и растянется на несколько миллисекунд. Есть какое-нибудь решение?
tinyCoder
2
Используйте romannurik.github.io/AndroidAssetStudio/index.html (выберите «Генератор значков запуска») для создания mdpi, hdpi, xhdpi и т. Д.
CoolMind
73

Я реализовал диалог прогресса до загрузки изображения, и это очень просто. Возьмите ImageView в относительной компоновке и поместите загрузчик прогресса в то же представление изображения. Примените приведенный ниже код и обработайте только видимость диалогового окна прогресса.

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

                }
            });
        }

Наслаждаться. :)

Аканкша Ратхор
источник
Спасибо .. это мне очень помогло :)
Zohair
2
Большой! Лучшее решение на данный момент, может использоваться в самых разных контекстах. :)
VVZen
7
На самом деле вам следует обратить внимание на слабые ссылки и объявить объект обратного вызова таким образом , чтобы избежать сборки мусора (иначе onSuccess никогда не будет вызван):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
Любой, кого сбивает с толку жаргон, «загрузчик прогресса - это плохой прогресс»,
Джо Махер
2
Вы пропустили добавление класса RoundedTransformation. Этот класс находится здесь gist.github.com/aprock/6213395
Md. Sajedul Karim
3

К сожалению, Пикассо не поддерживает анимированные заполнители.

Один из способов обойти это - разместить ImageView в FrameLayout с анимированным рисунком внизу. Таким образом, когда Picasso загружает изображение, оно загружается поверх анимированного заполнителя, давая пользователю желаемый эффект.

В качестве альтернативы вы можете загрузить изображение в Target . Тогда по умолчанию будет отображаться индикатор выполнения, а при вызове метода onBitmapLoaded вы можете скрыть его и отобразить изображение. Вы можете увидеть базовую реализацию этого здесь

Майкл
источник
3
Пикассо делает поддержку анимированных заполнителей. Вы пишете файл анимации для рисования (включает список анимации с несколькими элементами, представляющими каждое изображение в анимации). Вы загружаете этот файл в новый объект AnimationDrawable, а затем передаете его в placeHolder () в конструкторе загрузчика Picasso.
Odaym
1

Просто добавьте атрибут формы в ответ DBragion, как показано ниже, и он будет работать как шарм. Удачного кодирования.

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

Вы также можете использовать Glide:

Glide.with(activity).load(url)
                    .apply(RequestOptions.centerInsideTransform())
                    .placeholder(R.drawable.progress_animation)
                    .into(imageview);
Тушар Латия
источник
1

Я нашел ответ на этот вопрос!

См. Https://github.com/square/picasso/issues/427#issuecomment-266276253

В дополнение к ответу @DBragion попробуйте ниже.

Теперь мы можем исправить высоту и ширину!

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

Я думаю, есть два ключевых момента.

  1. используйте noFade ()

  2. установите scaleType image_view на "CENTER_INSIDE"

Юсуке Ёнехара
источник
0

Я заставил это работать следующим образом:

  1. Создал drawable (нашел где-то в Интернете) и поместил его в 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. В моем элементе для GridView добавлен элемент 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. В Адаптер добавлен целевой объект со следующими параметрами, где плакат и счетчик являются ссылками на ImageView и ProgressBar:

    // Цель для отображения / скрытия ProgressBar на 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. Результаты будут такими же при загрузке - круг вращается (извините за этот снимок экрана, но изображения появляются слишком быстро): ScreenShot

Дмитрий Каратаев
источник
0

Для тех, кто пытается использовать технику DBragion: убедитесь, что у вас установлена ​​последняя версия Picasso, иначе она не будет вращаться. Моя не работала, пока я не использовал версию 2.5.2.

compile 'com.squareup.picasso:picasso:2.5.2'
Джесси Абруццо
источник
6
Это должен быть комментарий под указанным ответом
Ojonugwa Jude Ochalifu
0

По этой ссылке Джейк Уортон сказал:

Нет. Мы используем Android BitmapFactory для всего декодирования изображений, и он не поддерживает анимированные GIF (к сожалению).

Тогда ты не можешь

Радеш
источник
0

Просто используйте Picasso PlaceHolder

  Picasso.get()
        .load(datas[position].artist?.image)
        .placeholder(R.drawable.music_image)
        .error(R.drawable.music_image)
        .into(holder.cardViewImage)
Эксель Стадерлин
источник