使用Glide库设置进度栏在可见图像加载完成后的可见性


90

嗨,我想有一个图像进度条,它将在图像加载时显示,但是当图像加载完成时,我想将其设置为消失。之前,我为此使用Picasso库。但是我不知道如何在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

我也建议您坚持使用毕加索(Picasso),除非您有充分的理由来更改图库
Chris

Answers:


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。


13
考虑隐藏在progressBaronException和,否则会无限期地旋转提供虚假的希望。一旦onException被称为Glide,除了设置要传递给的内容外,什么都不会做.error()
TWiStErRob 2015年

2
如果您在加载图像之前离开Fragment / Activity,则可能导致NullPointerException。
aProperFox'3

1
我并没有激昂您创建内部类侦听器,这只是显示用于完成任务的工具的最简洁的方法。
Yaroslav

1
当然,我通过在超级调用之前在onDestroyVIew()中添加一个调用来解决此问题,该调用要求说Glide.clear(yourImageView)
aProperFox

7
注意:.listener必须在.into()
Ahmed Mostafa '18

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
还需要导入目标: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. 在调用以下提及方法之前,设置进度条的可见性可见。

    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”有什么用?我不能只使用侦听器吗?如果是这样,我如何使它开始加载而没有“进入?”
android开发人员

@android开发人员,我知道您可以不使用
Narek Hayrapetyan

它可以尝试
Narek Hayrapetyan

但是,如果我不使用“ 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 { }给滑翔机.listener()

接受Glide的RequestListener的GlideImpl.kt类

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并将其放在drawable文件夹中。

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

一旦加载了网址图片,缩略图就会消失。加载缓存的图像时,缩略图立即消失。


4
我认为这是因为它没有回答问题:OP已经有一个令他满意的微调器。这也与Android最佳做法背道而驰:使用GIF作为微调器需要90秒钟,并且会显着增加APK大小;并且将GIF放入drawable本身是不好的,因为它不是由框架加载的,它应该位于其中rawassets充其量。当应用程序中发生事件时,更改可见性并没有错,Android就是为此而设计的。
TWiStErRob

1
在GIF解码发生时,用户还将看到一个空白区域,它是异步的而不是立即的。您还正在-RESULT缓存进度栏,这意味着需要一段时间才能加载。应该最大程度地SOURCE缓存GIF以提高效率;但是由于这是本地文件,因此缓存必须NONE不要在磁盘上复制它,从而消耗更多的用户空间。
TWiStErRob'3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.