Установите видимость индикатора выполнения, исчезающего после завершения загрузки изображения с помощью библиотеки Glide

90

Привет, я хочу иметь индикатор выполнения для изображения, который будет отображаться во время загрузки изображения, но когда загрузка изображения будет завершена, я хочу, чтобы он исчез. Раньше я использовал для этого библиотеку Пикассо. Но я не знаю, как использовать его с библиотекой Glide. Я догадываюсь, что есть какая-то функция готовности к ресурсам, но не знаю, как ее использовать. Может кто-нибудь мне помочь?

Код для библиотеки Пикассо

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

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

Как мне сделать это с помощью Glide?

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

Я могу загрузить изображение с помощью Glide, но как я могу написать progressBar.setVisibility(View.GONE);где-нибудь в коде, если изображение загружается?

Харирам
источник
2
Почему вы изменили свою библиотеку? Пикассо великолепен.
tasomaniac
Я также рекомендовал бы придерживаться Пикассо, если у вас нет веской причины менять библиотеки
Крис

Ответы:

229

Вопрос довольно старый, и я не знаю, какова была ситуация со скольжением в те времена, но теперь это можно легко сделать с помощью слушателя (не так, как предлагается в ответе, выбранном как правильный).

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

Вы возвращаете true, если хотите обрабатывать такие вещи, как анимация самостоятельно, и false, если хотите, чтобы glide справился с ними за вас.

Ярослав
источник
13
Рассматривает Скрытие progressBarв onExceptionа, в противном случае он будет вращаться до бесконечности давать ложную надежду. После того, как onExceptionвызывается Glide, ничего не будет делать, кроме установки того, что передается .error().
TWiStErRob
2
Это может привести к исключению NullPointerException, если вы оставите фрагмент / действие до загрузки изображения.
aProperFox 03
1
Я не призываю вас создавать слушателей внутреннего класса, просто самый краткий способ показать инструмент для выполнения задачи.
Ярослав
1
Конечно, я решил эту проблему, добавив вызов в onDestroyVIew () перед супер-вызовом, чтобы сказать Glide.clear (yourImageView)
aProperFox
7
ПРИМЕЧАНИЕ: .listenerнеобходимо позвонить раньше.into()
Ахмед Мостафа
31

Если вы хотите сделать это в KOTLIN, вы можете попробовать так:

    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
Также необходимо импортировать Target:import com.bumptech.glide.request.target.Target
Gibolt
@Gibolt, это беспокоило меня 10 минут подряд
johnrao07
17

Мой ответ был основан на устаревших API. См. Здесь для получения более свежего ответа.

Брайан Силлс
источник
.listener()лучше, потому что вы получите больше информации о своей нагрузке (модель, кеш памяти и т. д.), поэтому вам будет проще выбрать более настраиваемую логику. RequestListenerтакже более стабилен, переопределение того, что Targetнужно создать, не даст вам преимущества в будущих исправлениях. Вы также можете легко создать файл VisibilityListener<T, R>, который можно будет повторно использовать в разных контекстах.
TWiStErRob
10

В виде исключения поставьте условие для повторного отображения 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

Вышеупомянутое решение работает для меня тоже очень хорошо, но когда я использую asBitmap () для загрузки изображения. Это не работает.

Нам нужно использовать 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);
            }
        });
Пратап
источник
Смотрите мой комментарий: stackoverflow.com/questions/26054420/… . Этот ответ хорошо демонстрирует то, что я там сказал.
TWiStErRob
7

GlideDrawable устарели, используйте простой 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
источник
4

В Котлине вы можете сделать как показано ниже

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)
Android Dev
источник
2
  1. В xml возьмите индикатор выполнения с высотой и шириной (match_parent).
  2. Перед вызовом нижеупомянутого метода установите видимость индикатора выполнения 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
    
Виджеш Джат
источник
Чем ваш ответ отличается от stackoverflow.com/a/31675796/3812404 ? Также пункт 1 не нужен.
HariRam
2

Обновить:

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);
Нарек Айрапетян
источник
Скажем, если у вас уже есть onResourceReady, какой толк от «в»? Разве я не могу использовать только слушателя? Если да, как я могу заставить его загружаться без "в"?
разработчик Android,
Разработчик @android, насколько я знаю, вы можете использовать без IN
Нарек Айрапетян
стоит попробовать
Нарек Айрапетян
Но если я не использую «в», я думаю, это предупреждает об этом.
разработчик Android
1

Как я все делал. более короткий путь, более чистый код

пример:

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)

Применение:

GlideImpl.OnCompleted {
    // completed
}

просто перейдите GlideImpl.OnCompleted { }к Glide's.listener()

GlideImpl.kt класс, который принимает RequestListener 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
        }
    }
}

и все!

Деннис Гонсалес
источник
0

Котлин путь

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

Это лучший ответ, так как он не использует никаких хаков, таких как настройка видимости, для получения желаемого результата.

Загрузите гифку индикатора выполнения, вызовите его progressbargifи поместите в папку с возможностью переноса.

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

Как только изображение URL загружено, эскиз исчезает. Миниатюра исчезает сразу после загрузки кэшированного изображения.

суку
источник
4
Я думаю, это потому, что он не отвечает на вопрос: у OP уже есть спиннер, которым он доволен. Это также противоречит лучшим методам Android: использование GIF в качестве счетчика - это уже 90-е годы и значительно увеличивает размер APK; а помещать GIF в drawableнего плохо само по себе, потому что он не загружается фреймворком, он должен быть внутри rawили assetsв лучшем случае. Нет ничего плохого в изменении видимости событий, происходящих в вашем приложении, Android создан для этого.
TWiStErRob
1
Пользователь также увидит пустое пространство во время декодирования GIF, оно асинхронно, а не сразу. Вы также RESULTкешируете индикатор выполнения, что означает, что загрузка займет некоторое время. GIF-файлы следует SOURCEв лучшем случае кэшировать для повышения эффективности; но поскольку это локальный файл, кеш не должен NONEдублировать его на диске, занимая еще больше пользовательского пространства.
TWiStErRob