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

所遇到的问题:

问题:服务端返回的图片没有返回尺寸,移动端无法确定图片比例,导致RecyclerView的图片无法充满屏幕或者被过渡拉伸,特别是在瀑布流布局中,严重影响用户体验
解决: 1. 服务端提供宽高 2. 动态计算宽高
思路: 使用Glide加载图片让其返回Bitmap,拿到Bitmap的宽高,然后计算屏幕的宽度,通过图片比例动态计算高度,最后设置给ImageView即可
代码 Kotlin:
【Glide动态获取宽高|Glide动态获取宽高,自动适配瀑布流布局,解决滑动跳动】这里图片加载使用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中清除缓存,这样使用基本上就没什么问题了,如果遇到问题或者更好的解决方法,请在下面留言。

    推荐阅读