Glide动态获取宽高,自动适配瀑布流布局,解决滑动跳动

所遇到的问题:

问题:服务端返回的图片没有返回尺寸,移动端无法确定图片比例,导致RecyclerView的图片无法充满屏幕或者被过渡拉伸,特别是在瀑布流布局中,严重影响用户体验

解决: 1. 服务端提供宽高 2. 动态计算宽高
思路: 使用Glide加载图片让其返回Bitmap,拿到Bitmap的宽高,然后计算屏幕的宽度,通过图片比例动态计算高度,最后设置给ImageView即可

代码 Kotlin:

这里图片加载使用Glide,其他的也类似,新建一个Glide工具类,提供常用方法。

 //请求头 ,不需要可以不加
  var header: HashMap = hashMapOf()

 companion object {
       //重要 图片的宽高的缓存,后面会讲
        var imageSize: HashMap = hashMapOf()

        private var glideUtils: GlideUtils? = null
        fun getGlide(): GlideUtils {
            if (glideUtils == null) {
                glideUtils = GlideUtils()
            }
            return glideUtils!!
        }
    }
  fun load(url: String): GlideUtils {
        this.url = url
        return glideUtils!!
    }

    fun with(context: Context): GlideUtils {
        this.mContext = context
        return glideUtils!!
    }

      //主要方法:
     fun into(view: ImageView, position: Int) {
          val glideUrl = GlideUrl(url, LazyHeaders.Builder()
                .addHeader("Authorization", "ToKen")
                .build())

        Glide.with(mContext!!).asBitmap().load(glideUrl).listener(object : RequestListener {
            override fun onLoadFailed(e: GlideException?, model: Any, target: Target, isFirstResource: Boolean): Boolean {
                return false
            }

            override fun onResourceReady(resource: Bitmap, model: Any, target: Target, dataSource: DataSource, isFirstResource: Boolean): Boolean {
                //拿到图片的宽和高
                var width = resource.width
                var height = resource.height
                //拿到当前屏幕的宽度的一半  如果是3列就除以3
                var screenWidthPx = mContext?.screenWidth()!! / 2
                //通过宽高比例动态计算高度,使图片撑满屏幕
                height *= (width / screenWidthPx)
                //设置图片的宽高
                val params = view.layoutParams
                //将图片的宽高放入hashmap缓存,下一次加载图片从缓存中取出宽高
                if (!imageSize.containsKey(position)) {
                    //设置图片的宽高
                    params?.width = width
                    params?.height = height
                    view.layoutParams = params
                    //存入缓存
                    imageSize[position] = ImageSize(width, height)
                    Log.d("图片的宽高", width.toString() + "---" + height)
                }
                return false
            }
        }).into(view)

注意:如果不使用缓存,那么首次加载的时候是没有问题的,如果用户向上滑动,由于RecyclerView的复用,会导致View的宽高获取上一个View宽高,导致View滑动过程中跳动,大小也会变化,导致显示错乱;

Adapter :

 override fun convert(helper: BaseViewHolder?, item: String?) { 
        val ivItem = helper?.getView(R.id.iv_item_pic)
        val params = ivItem?.layoutParams 
       //  使用缓存中宽高,如果有的话
        if (GlideUtils.imageSize.containsKey(helper?.position)) {
            params?.width = GlideUtils.imageSize.get(helper?.position)?.width
            params?.height = GlideUtils.imageSize.get(helper?.position)?.height
            ivItem?.layoutParams = params     
        } 
        GlideUtils.getGlide().with(mContext).load(item!!).into(ivItem!!, helper.position) 
    }
最后: 不要忘了在onDestroy中清除缓存,这样使用基本上就没什么问题了,如果遇到问题或者更好的解决方法,请在下面留言。

你可能感兴趣的:(Glide动态获取宽高,自动适配瀑布流布局,解决滑动跳动)