Android uses setRectToRect to implement Bitmap scaling RectF animation based on Matrix matrix scale, Kotlin (1)
Based on Matrix, control the width and height of the target RectF of Bitmap's setRectToRect. Starting from a very small width and height, iteratively increases the width and height of the target RectF of setRectToRect, adding a certain delay to each iteration to achieve animation based on Matrix.
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.RectF
import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class MainActivity : AppCompatActivity() {
private var iv: ImageView? = null
private var result: ImageView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
iv = findViewById(R.id.iv)
result = findViewById(R.id.result)
}
override fun onResume() {
super.onResume()
result?.postDelayed({
val bmp = BitmapFactory.decodeResource(resources, R.mipmap.mypic)
matrixAnimScale(bmp, iv!!.width, iv!!.height)
}, 500)
}
private fun matrixAnimScale(srcBmp: Bitmap, width: Int, height: Int) {
val delayTime = 1L //动画之间的间隔。
val step = 100f //100次缩放绘制,每步延时delayTime毫秒,总计 delayTime*step 毫秒完成动画。
val deltaW: Float = width / step
val deltaH: Float = height / step
CoroutineScope(Dispatchers.IO).launch {
var w = 0f
var h = 0f
for (i in 0 until step.toInt()) {
delay(delayTime)
w += deltaW
h += deltaH
val bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val c = Canvas(bmp)
c.drawColor(Color.BLUE)
val src = RectF(0f, 0f, srcBmp.width.toFloat(), srcBmp.height.toFloat())
val dst = RectF(0f, 0f, w, h)
val mx = Matrix()
mx.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER)
c.drawBitmap(srcBmp, mx, null)
withContext(Dispatchers.Main) {
result?.setImageBitmap(bmp)
}
}
}
}
}
There are two ImageViews above and below. The ImageView below displays a Bitmap that is continuously enlarged from small to large (the same as the Bitmap displayed by the ImageView above):
The final animation ends: