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

Posted

技术标签:

【中文标题】使用 Glide 库设置完成图像加载后进度条的可见性【英文标题】:Set visibility of progress bar gone on completion of image loading using Glide library 【发布时间】:2014-11-21 03:52:30 【问题描述】:

您好,我想要一个图像进度条,它会在图像加载时显示,但是当图像加载完成时,我想将其设置为消失。早些时候,我为此使用了 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);

【问题讨论】:

你为什么要改变你的图书馆?毕加索很棒。 我还建议您坚持使用毕加索,除非您有充分的理由更改库 【参考方案1】:

科特林方式

showProgressBar()
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 
                        hideProgressBar()
                        return false
                    

                    override fun onResourceReady(
                        resource: Drawable?,
                        model: Any?,
                        target: Target<Drawable>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean 
                        img_product_banner.visibility = View.VISIBLE
                        hideProgressBar()
                        return false
                    

                ).placeholder(R.drawable.placeholder)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(img_product_banner)

【讨论】:

【参考方案2】:

我是如何做事的。更短的方式,更简洁的代码

示例:

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 的 .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
        
    

就是这样!

【讨论】:

【参考方案3】:

更新:

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 开发者我知道你可以不用进入 它可以尝试 但如果我不使用 "into" ,我认为它会发出警告。【参考方案4】:

在 Kotlin 中你可以像下面那样做

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)

【讨论】:

【参考方案5】:

不推荐使用 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);

【讨论】:

【参考方案6】:

如果你想在 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)

【讨论】:

还需要导入Target:import com.bumptech.glide.request.target.Target @Gibolt 这连续困扰了我 10 分钟【参考方案7】:
    在 xml 中获取具有高度和宽度的进度条(match_parent)。

    在调用下面提到的方法之前,设置进度条可见性可见。

    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
    

【讨论】:

您的回答与***.com/a/31675796/3812404 有何不同?另外,第 1 点也不需要。【参考方案8】:

这是最好的答案,因为它不使用设置可见性等任何技巧来获得所需的输出。

下载进度条的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);

一旦加载 url 图片,缩略图就会消失。加载缓存的图像后,缩略图会立即消失。

【讨论】:

我认为这是因为它没有回答问题:OP 已经有了一个他很满意的微调器。这也违反了 Android 的最佳实践:使用 GIF 作为微调器是如此 90 年代,并显着增加了 APK 大小;并且将 GIF 放入 drawable 本身就是不好的,因为它不是由框架加载的,它最多应该在 rawassets 中。当您的应用中发生事件时更改可见性并没有错,Android 就是为此而设计的。 当 GIF 解码发生时,用户还会看到一个空白空间,它是异步的,不是立即的。你也是RESULT-缓存进度条,这意味着加载需要一段时间。 GIF 最好是 SOURCE-cached 以提高效率;但由于这是一个本地文件,缓存需要NONE 才能不在磁盘上复制它,从而消耗更多的用户空间。【参考方案9】:

在异常情况下再次显示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);

【讨论】:

【参考方案10】:

我的回答是基于过时的 API。请参阅here 了解更多最新答案。

【讨论】:

.listener() 更好,因为您将收到有关您的负载(模型、内存缓存等)的更多信息,因此更容易决定更多自定义逻辑。 RequestListener 也更稳定,覆盖 Target 创建不会给您带来未来修复的好处。您还可以轻松创建一个VisibilityListener&lt;T, R&gt;,以便在不同的上下文中重复使用。【参考方案11】:

问题相当老了,我不知道当时滑翔的情况如何,但现在可以通过听众轻松完成(而不是在选择正确的答案中提出)。

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,如果你想让 glide 为你处理它们,你返回 false。

【讨论】:

考虑将progressBar 也隐藏在onException 中,否则它会无限期地旋转,给人以虚假的希望。一旦onException 被调用,Glide 只会设置传递给.error() 的内容。 如果您在图像加载之前离开 Fragment/Activity,这可能会导致 NullPointerException。 我并不是在鼓动您创建内部类侦听器,这只是展示完成任务的工具的最简洁方式。 当然,我通过在 onDestroyVIew() 中添加一个调用来解决这个问题,在超级调用之前说 Glide.clear(yourImageView) 注意:.listener 必须在 .into() 之前调用【参考方案12】:

上述解决方案对我也很有效,但是当我使用 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);
            
        );

【讨论】:

查看我的评论:***.com/questions/26054420/…。这个答案很好地证明了我在那里所说的。

以上是关于使用 Glide 库设置完成图像加载后进度条的可见性的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的应用中使用 Glide 加载图像?

Glide4.10.0加载图片进度监听

带有图像和圆形进度条的圆形按钮

用于 onActivityCreated 中通用图像加载器的片段中进度条的 NullPointerException

kivy:带有进度条的弹出窗口

网页加载进度条的实现