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

1
Я не агітую вас створювати слухачів внутрішнього класу, а лише найкоротший спосіб показати інструмент для виконання завдання.
Ярослав

1
Звичайно, я вирішив це, додавши виклик у onDestroyVIew () перед супервикликом, щоб сказати Glide.clear (yourImageView)
aProperFox 03.03.16

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, це мене хвилювало 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. Перед викликом нижче методу згадування встановіть видимість індикатора прогресу Видимий.

    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, яка користь від "into"? Чи не можу я просто користуватися слухачем наодинці? Якщо так, то як я можу змусити його розпочати завантаження без "into?"
розробник Android

Розробник @android, як я знаю, ви можете використовувати, не входячи
Нарек Хайрапетян,

варто спробувати
Нарек Хайрапетян,

Але якщо я не використовую "into", я думаю, це попереджає про це.
розробник 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

Це найкраща відповідь, оскільки вона не використовує будь-який хак, як встановлення видимості, щоб отримати бажаний результат.

Завантажте gif прогрес-панелі та зателефонуйте йому 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.