Сначала я решил использовать это решение , и оно заработало, как и ожидалось. Но затем я использовал решение, которое pskink посоветовал мне использовать. Это проще, короче и вернее моего предыдущего выбора. Пример:
interface OnMatrixChangeListener {
fun onChange(theMatrix: Matrix)
}
class ChartView2(context: Context, attrs: AttributeSet?) : View(context, attrs), OnMatrixChangeListener {
private var theMatrix = Matrix()
private var detector = MatrixGestureDetector(theMatrix, this)
private var paint = Paint()
private var colors = intArrayOf(Color.RED, Color.GREEN, Color.BLUE)
private var colorNames = arrayOf("RED", "GREEN", "BLUE")
private var centers = arrayOf(PointF(100f, 100f), PointF(400f, 100f), PointF(250f, 360f))
var inverse = Matrix()
override fun onTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_DOWN) {
theMatrix.invert(inverse)
val pts = floatArrayOf(event.x, event.y)
inverse.mapPoints(pts)
for (i in colors.indices) {
if (Math.hypot((pts[0] - centers[i].x).toDouble(), (pts[1] - centers[i].y).toDouble()) < 100)
Log.d("abcd", colorNames[i] + " circle clicked")
}
}
detector.onTouchEvent(event)
return true
}
override fun onDraw(canvas: Canvas) {
canvas.concat(theMatrix)
for (i in colors.indices) {
paint.color = colors[i]
canvas.drawCircle(centers[i].x, centers[i].y, 100f, paint)
}
}
override fun onChange(theMatrix: Matrix) {
invalidate()
}
}
internal class MatrixGestureDetector(private val mMatrix: Matrix, listener: OnMatrixChangeListener) {
private var ptpIdx = 0
private val mTempMatrix = Matrix()
private val mListener: OnMatrixChangeListener?
private val mSrc = FloatArray(4)
private val mDst = FloatArray(4)
private var mCount: Int = 0
init {
this.mListener = listener
}
fun onTouchEvent(event: MotionEvent) {
if (event.pointerCount > 2) {
return
}
val action = event.actionMasked
val index = event.actionIndex
when (action) {
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> {
val idx = index * 2
mSrc[idx] = event.getX(index)
mSrc[idx + 1] = event.getY(index)
mCount++
ptpIdx = 0
}
MotionEvent.ACTION_MOVE -> {
for (i in 0 until mCount) {
val idx = ptpIdx + i * 2
mDst[idx] = event.getX(i)
mDst[idx + 1] = event.getY(i)
}
mTempMatrix.setPolyToPoly(mSrc, ptpIdx, mDst, ptpIdx, mCount)
mMatrix.postConcat(mTempMatrix)
mListener?.onChange(mMatrix)
System.arraycopy(mDst, 0, mSrc, 0, mDst.size)
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> {
if (event.getPointerId(index) == 0) ptpIdx = 2
mCount--
}
}
}
}