Установите видимость индикатора выполнения, исчезающего после завершения загрузки изображения с помощью библиотеки 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);

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)

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.