Android Glide批量加载Bitmap,拼接组装大Bitmap,更新单个AppCompatImageView,Kotlin(3)
这篇 Android Glide批量加载Bitmap,拼接组装大Bitmap,更新单个AppCompatImageView,Kotlin(2)-CSDN博客
遗留两个问题:
(1)当最后一行不满ROW_SIZE时候,根本就不会显示。
(2)即便显示出来,因为绘制是按照ROW_SIZE绘满一行,导致实际不满一行的位置显示为灰色占位颜色块。
以上问题均是在 BatchBitmapView,改造:
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.util.AttributeSet
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
class BatchBitmapView @JvmOverloads constructor(
val mCtx: Context,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatImageView(mCtx, attributeSet, defStyleAttr) {
private val mData = mutableListOf<DataBean>()
private val mTargets = mutableListOf<Target<Bitmap>>()
private var mRealSize: Int = 0
companion object {
const val TAG = "fly/BatchBitmapView"
const val ROW_SIZE = 16 //一行多少个bitmap
const val IMAGE_SIZE = 200 //每个小格子图片的尺寸
var mScreenWidth: Int = 0
var mScreenHeight: Int = 0
//整数相除,精度损失的平衡因子
const val BALANCE_FACTOR = 1
}
init {
//scaleType = ScaleType.FIT_CENTER
if (mScreenWidth == 0) {
mScreenWidth = resources.displayMetrics.widthPixels
}
if (mScreenHeight == 0) {
mScreenHeight = resources.displayMetrics.widthPixels / ROW_SIZE + BALANCE_FACTOR
}
}
fun setRowBitmapData(rows: ArrayList<MainActivity.MyData>?, position: Int) {
mData.clear()
mTargets.forEach {
//如果不清除,会发生有些图错放位置。
Glide.with(mCtx).clear(it)
}
mTargets.clear()
var loadCount = 0
mRealSize = rows?.size!!
rows?.forEachIndexed { _, myData ->
val target = Glide.with(mCtx)
.asBitmap()
.centerCrop()
.override(IMAGE_SIZE)
.load(myData.path).addListener(object : RequestListener<Bitmap> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>, isFirstResource: Boolean): Boolean {
loadCount++
val errorBmp = BitmapFactory.decodeResource(mCtx.resources, android.R.drawable.stat_notify_error)
refresh(loadCount, errorBmp)
return false
}
override fun onResourceReady(
resource: Bitmap,
model: Any,
target: Target<Bitmap>?,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
loadCount++
refresh(loadCount, resource)
return false
}
})
.preload(IMAGE_SIZE, IMAGE_SIZE)
mTargets.add(target)
}
}
fun refresh(loadCount: Int, bmp: Bitmap) {
val bean = DataBean(bmp)
mData.add(bean)
if (loadCount == mRealSize) {
val jBmp = joinBitmap()
(mCtx as AppCompatActivity).runOnUiThread {
this@BatchBitmapView.setImageBitmap(jBmp)
}
}
}
private fun joinBitmap(): Bitmap {
val bmp = Bitmap.createBitmap(IMAGE_SIZE * mRealSize, IMAGE_SIZE, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bmp)
canvas.drawColor(Color.LTGRAY)
mData.forEachIndexed { idx, dataBean ->
canvas.drawBitmap(dataBean.bitmap, IMAGE_SIZE * idx.toFloat(), 0f, null)
}
return bmp
}
data class DataBean(val bitmap: Bitmap)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
if (mRealSize == ROW_SIZE) {
setMeasuredDimension(mScreenWidth, mScreenHeight)
} else {
val w = (mScreenWidth / ROW_SIZE) * mRealSize
setMeasuredDimension(w, mScreenHeight)
}
}
}