所遇到的问题:
问题:服务端返回的图片没有返回尺寸,移动端无法确定图片比例,导致RecyclerView的图片无法充满屏幕或者被过渡拉伸,特别是在瀑布流布局中,严重影响用户体验
解决: 1. 服务端提供宽高 2. 动态计算宽高
思路: 使用Glide加载图片让其返回Bitmap,拿到Bitmap的宽高,然后计算屏幕的宽度,通过图片比例动态计算高度,最后设置给ImageView即可
代码 Kotlin:
这里图片加载使用Glide,其他的也类似,新建一个Glide工具类,提供常用方法。
//请求头 ,不需要可以不加
var header: HashMap<String, String> = hashMapOf()
companion object {
//重要 图片的宽高的缓存,后面会讲
var imageSize: HashMap<Int, ImageSize> = 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<Bitmap> {
override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Bitmap>, isFirstResource: Boolean): Boolean {
return false
}
override fun onResourceReady(resource: Bitmap, model: Any, target: Target<Bitmap>, 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<ImageView>(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)
}