【问题标题】:Set visibility of progress bar gone on completion of image loading using Glide library使用 Glide 库设置完成图像加载后进度条的可见性
【发布时间】: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);

【问题讨论】:

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

标签: android imageview android-glide


【解决方案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】:
          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
            

          【讨论】:

          【解决方案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);
                        }
                    });
            

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-05-20
            • 2014-09-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-10-22
            • 1970-01-01
            相关资源
            最近更新 更多