测试RecyclerView使用glide加载图片自适应大小的时候发现,第一次是正常的,可是在二次刷新的的时候或者滑动隐藏重新加载出来的时候图片的大小都会变小,甚至三次四次刷新的时候会更小,后面研究解决了一下。
一、先说解决办法。
.解决思路
在第一次加载的时候利用glide的加载监听方法获取保存图片的宽高,在二次以后的加载的时候利用glide的override方法设置该图片的大小。
我是用了一个map来保存的map(url,bean(含有图片宽高属性的bean))
下面给出主要的代码(kotlin的,不过用java的应该也能看懂吧)
1.recyclerview的adapter适配器
package com.zm.androidtest.adapter
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.LayoutInflater.from
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.zm.androidtest.R
import com.zm.androidtest.bean.DataBean
import com.zm.androidtest.bean.ImageGlideBean
import kotlinx.android.synthetic.main.layout_recyclerview_item.view.*
import kotlinx.android.synthetic.main.layout_recyclerview_item.view.tv_name
import kotlinx.android.synthetic.main.layout_students_list_item.view.*
/**
* 可参考 https://www.jianshu.com/p/4357783bd242
* 或者 https://blog.csdn.net/sinat_35241409/article/details/81871448
*/
class MyRecyclerAdapter (var list:MutableList): RecyclerView.Adapter() {
var imgMap = HashMap()//用这个map来保存图片的参数,key用url,值设置为一个属性有图片的宽高的变量
private var itemClickListener: IKotlinItemClickListener? =null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflate = from(parent?.context).inflate(R.layout.layout_recyclerview_item,null)
return MyHolder(inflate)
}
override fun getItemCount(): Int {
return list.size
}
//listview可参照https://www.jianshu.com/p/4357783bd242
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(holderis MyHolder){
holder.bind(list[position])
}
// 点击事件
holder.itemView.setOnClickListener{
itemClickListener?.onItemClickListener(position)
}
}
override fun getItemViewType(position: Int): Int {
when(position){
//多布局
in 1..2 ->
return 1
else ->return super.getItemViewType(position)
}
}
//布局1
inner class MyHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val requestOptions = RequestOptions()
.error(R.mipmap.ic_book_def)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.dontAnimate()
fun bind(date: DataBean){
itemView.tv_num.text = (adapterPosition+1).toString()+"."
itemView.tv_name.text=date.name
//如果保存的imgMap里面没有包含图片的url,就先加载一次,并根据url保存该图片的宽高参数
if(!imgMap.containsKey(date.imgUrl))
{
Glide.with(itemView.context)
.asBitmap()
.load(date.imgUrl)
.apply(requestOptions)
.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 {
Log.i("image","onResourceReady---图片加载成功----"+(adapterPosition+1)+"---width=="+resource?.width+",height=="+resource?.height+"----url=="+date.imgUrl+"-----imgMap.size="+imgMap.size)
if(!imgMap.containsKey(date.imgUrl))
{
imgMap.put(date.imgUrl, ImageGlideBean(date.imgUrl,resource?.width!!,resource?.height!!))
}
return false
}
})
.into(itemView.iv_icon)
}
//如果该图片的url已经被保存过了,则根据url取出该图片的宽高指定宽高后加载
else{
Log.i("image","onResourceReady---图片加载成功----"+(adapterPosition+1)+"----url=="+date.imgUrl+"-----imgMap.size="+imgMap.size)
Glide.with(itemView.context)
.asBitmap()
.load(date.imgUrl)
.override(imgMap.get(date.imgUrl)?.width!!,imgMap.get(date.imgUrl)?.height!!)
.into(itemView.iv_icon)
}
}
var tv_name:TextView = itemView.findViewById(R.id.tv_name)
}
// 提供set方法
fun setOnKotlinItemClickListener(itemClickListener: IKotlinItemClickListener) {
this.itemClickListener = itemClickListener
}
//自定义接口
interface IKotlinItemClickListener {
fun onItemClickListener(position: Int)
}
//在需要清空的时候调用清空map数据
fun cleanUrlMap()
{
imgMap.clear()
}
}
2.用来保存在map里面的bean类
data class ImageGlideBean
(
var imgUrl:String,
var width:Int,
var height:Int
)
3.列表选项的 layout_recyclerview_item 布局
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/recycleview_item_bg">
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1."
android:layout_centerVertical="true"
android:textSize="40px"/>
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:focusable="false"
android:scaleType="centerInside"
android:layout_toRightOf="@id/tv_num"
android:layout_marginLeft="20px"/>
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="250px"
android:layout_toRightOf="@id/iv_icon"
android:textSize="20sp"
android:padding="15dp"
android:gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:layout_centerVertical="true"/>
经过上面的设置不论是重新setAdapter还是adapter?.notifyDataSetChanged()刷新列表的时候图片的大小都不会改变了,这样就解决了该问题了。 为什么会造成这样的结果也是没能探究出来,搞了好久都解决不了,可能是holder里面的什么缓存导致的吧