所遇到的問題:
問題:服務(wù)端返回的圖片沒有返回尺寸叨橱,移動端無法確定圖片比例,導致RecyclerView的圖片無法充滿屏幕或者被過渡拉伸,特別是在瀑布流布局中败匹,嚴重影響用戶體驗
解決: 1. 服務(wù)端提供寬高 2. 動態(tài)計算寬高
思路: 使用Glide加載圖片讓其返回Bitmap,拿到Bitmap的寬高撮胧,然后計算屏幕的寬度桨踪,通過圖片比例動態(tài)計算高度,最后設(shè)置給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
//通過寬高比例動態(tài)計算高度,使圖片撐滿屏幕
height *= (width / screenWidthPx)
//設(shè)置圖片的寬高
val params = view.layoutParams
//將圖片的寬高放入hashmap緩存,下一次加載圖片從緩存中取出寬高
if (!imageSize.containsKey(position)) {
//設(shè)置圖片的寬高
params?.width = width
params?.height = height
view.layoutParams = params
//存入緩存
imageSize[position] = ImageSize(width, height)
Log.d("圖片的寬高", width.toString() + "---" + height)
}
return false
}
}).into(view)
注意:如果不使用緩存汽纠,那么首次加載的時候是沒有問題的,如果用戶向上滑動傀履,由于RecyclerView的復(fù)用虱朵,會導致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)
}