class MultiTouchCoordinateView @JvmOverloads constructor(
context: Context, @Nullable attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : View(context, attrs, defStyleAttr, defStyleRes) {
companion object {
private const val IMAGE_SIZE = 200F
}
private val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
private var downX: Float = 0F
private var downY: Float = 0F
private var offsetX: Float = 0F
private var offsetY: Float = 0F
private var preOffsetX: Float = 0F
private var preOffsetY: Float = 0F
private val bitmap: Bitmap by lazy {
getTargetWidthBitmap(dp2px(IMAGE_SIZE).toInt(), resources)!!
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawBitmap(bitmap, offsetX, offsetY, paint)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
var pointerCount = event.pointerCount
var sunX: Float = 0F
var sumY: Float = 0F
var focusX: Float = 0F
var focusY: Float = 0F
for (i in 0 until pointerCount) {
if (event.actionMasked != MotionEvent.ACTION_POINTER_UP || i != event.actionIndex) {
sunX += event.getX(i)
sumY += event.getY(i)
}
}
if (event.actionMasked == MotionEvent.ACTION_POINTER_UP) {
pointerCount -= 1
}
focusX = sunX / pointerCount
focusY = sumY / pointerCount
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
downX = focusX
downY = focusY
return true
}
MotionEvent.ACTION_MOVE -> {
offsetX = focusX - downX + preOffsetX
offsetY = focusY - downY + preOffsetY
invalidate()
}
MotionEvent.ACTION_POINTER_DOWN,
MotionEvent.ACTION_POINTER_UP -> {
downX = focusX
downY = focusY
preOffsetX = offsetX
preOffsetY = offsetY
}
MotionEvent.ACTION_UP -> {
preOffsetX = offsetX
preOffsetY = offsetY
}
}
return super.onTouchEvent(event)
}
private fun dp2px(dp: Float) = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
Resources.getSystem().displayMetrics
)
private fun getTargetWidthBitmap(targetWidth: Int, resources: Resources): Bitmap? {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeResource(resources, R.drawable.wechat, options)
options.inJustDecodeBounds = false
options.inDensity = options.outWidth
options.inTargetDensity = targetWidth
return BitmapFactory.decodeResource(resources, R.drawable.wechat, options)
}
}