三种类型 :接力型 /配合型 /单独型
单点触控
- package com.example.myapplication.view
-
- import android.content.Context
- import android.graphics.Canvas
- import android.graphics.Paint
- import android.util.AttributeSet
- import android.view.MotionEvent
- import android.view.View
- import com.example.myapplication.dp
-
- class MultiTouchView1(context: Context, attrs: AttributeSet) : View(context, attrs) {
-
- private val bitmap = getBitmap()
- private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
-
- private var offsetX = 0f //初始位置
- private var offsetY = 0f
-
- private var downX = 0f //按下的位置
- private var downY = 0f
-
- private var originalOffsetX = 0f //偏移位置
- private var originalOffsetY = 0f
-
- override fun onDraw(canvas: Canvas) {
- super.onDraw(canvas)
- canvas.drawBitmap(bitmap, offsetX, offsetY, paint)
- }
-
- override fun onTouchEvent(event: MotionEvent): Boolean {
- when (event.actionMasked) {
- MotionEvent.ACTION_DOWN -> {
- downX = event.x
- downY = event.y
- originalOffsetX = offsetX
- originalOffsetY = offsetY
-
- }
- MotionEvent.ACTION_MOVE -> {
- offsetX = event.x - downX + originalOffsetX
- offsetY = event.y - downY + originalOffsetY
- invalidate()
- }
- }
- return true
- }
- }

触摸事件序列是针对View而不是手指
x,y ,index ,id 属于一个point ,一个序列,getX 获取index为0的手指位置
- public final float getX() {
- return nativeGetAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT);
- }
point_move 两个point,当第二根手指up,index会设置为0而不是1,有时候第0根手指down 为0index的会给按下的,然后0变为1
index作用是在发生MotionEvnent时,通过index遍历每个Point的操作
getX(),getX(index),index通过evnent.pointCount获取
for遍历event.point,通过getX(index) 如果某一个point抬起会报错 找不到Index,这时可以通过id查找
- MotionEvent.ACTION_MOVE -> {
-
- event.getX(event.actionIndex) //正在按下手指的ID
- event.getX(event.findPointerIndex(downId)) //通过ID获取
- }
action_move 不适合这种方法,因为在实时移动 更新,没有所谓的Point 也就是index ,id,只有在down / up 才有意义
接力型
- package com.example.myapplication.view
-
- import android.content.Context
- import android.graphics.Canvas
- import android.graphics.Paint
- import android.util.AttributeSet
- import android.view.MotionEvent
- import android.view.View
- import com.example.myapplication.dp
-
-
- class MultiTouchView1(context: Context, attrs: AttributeSet) : View(context, attrs) {
-
- private val bitmap =getBitmap()
- private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
-
- private var offsetX = 0f //初始位置
- private var offsetY = 0f
-
- private var downX = 0f //按下的位置
- private var downY = 0f
-
- private var originalOffsetX = 0f //偏移位置
- private var originalOffsetY = 0f
-
- private var trackingPointerId = 0 //当前按下的手指ID
-
- override fun onDraw(canvas: Canvas) {
- super.onDraw(canvas)
- canvas.drawBitmap(bitmap, offsetX, offsetY, paint)
- }
-
- override fun onTouchEvent(event: MotionEvent): Boolean {
- when (event.actionMasked) {
- MotionEvent.ACTION_DOWN -> {
- trackingPointerId = event.getPointerId(0)
- downX = event.x
- downY = event.y
- originalOffsetX = offsetX
- originalOffsetY = offsetY
-
- }
-
- //多个
- MotionEvent.ACTION_POINTER_DOWN -> {
- val actionIndex = event.actionIndex
- trackingPointerId = event.getPointerId(actionIndex) //按下的手指序号获取ID
- //更新 接管
- downX = event.getX(actionIndex)
- downY = event.getY(actionIndex)
- originalOffsetX = offsetX
- originalOffsetY = offsetY
- }
-
- MotionEvent.ACTION_POINTER_UP -> {
- val actionIndex = event.actionIndex
- val pointerId = event.getPointerId(actionIndex)
- if (pointerId == trackingPointerId) {
- //如果是正在跟踪的手指 进行替换
- val newIndex = if (actionIndex == event.pointerCount - 1) {
- event.pointerCount - 2
- } else {
- event.pointerCount - 1
- }
-
- trackingPointerId = event.getPointerId(newIndex) //按下的手指序号获取ID
- //更新 接管
- downX = event.getX(newIndex)
- downY = event.getY(newIndex)
- originalOffsetX = offsetX
- originalOffsetY = offsetY
- }
- }
- MotionEvent.ACTION_MOVE -> {
-
- val index = event.findPointerIndex(trackingPointerId)
- offsetX = event.getX(index) - downX + originalOffsetX
- offsetY = event.getY(index) - downY + originalOffsetY
- invalidate()
- }
- }
- return true
- }
- }
配合型:
- package com.example.myapplication.view
-
- import android.content.Context
- import android.graphics.Canvas
- import android.graphics.Paint
- import android.util.AttributeSet
- import android.view.MotionEvent
- import android.view.View
- import com.example.myapplication.dp
- import com.example.myapplication.getAvatar
-
-
- //双指滑动
- class MultiTouchView2(context: Context, attrs: AttributeSet) : View(context, attrs) {
-
- private val bitmap = getAvatar(resources, 200.dp.toInt())
- private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
-
- private var offsetX = 0f //初始位置
- private var offsetY = 0f
-
- private var downX = 0f //按下的位置
- private var downY = 0f
-
- private var originalOffsetX = 0f //偏移位置
- private var originalOffsetY = 0f
-
-
- override fun onDraw(canvas: Canvas) {
- super.onDraw(canvas)
- canvas.drawBitmap(bitmap, offsetX, offsetY, paint)
- }
-
- override fun onTouchEvent(event: MotionEvent): Boolean {
- val focusX : Float//焦点 两值相加 /2
- val focusY : Float
- var pointerCount = event.pointerCount
- var sumX = 0f
- var sumY = 0f
- val inPointerUp = event.actionMasked == MotionEvent.ACTION_POINTER_UP //如果是抬起
- for (i in 0 until pointerCount){
- if (!(inPointerUp && i == event.actionIndex)){ //当前位置并且不是抬起 则计算
- sumX += event.getX(i) //得到每个点的坐标
- sumY += event.getY(i)
- }
- }
-
- if (inPointerUp){
- pointerCount -- //处理额外偏移
- }
- focusX = sumX / pointerCount //得到焦点值 当抬起后count会变
- focusY = sumY /pointerCount
-
- when (event.actionMasked) {
- MotionEvent.ACTION_DOWN,MotionEvent.ACTION_POINTER_DOWN, MotionEvent.ACTION_POINTER_UP -> {
- downX = focusX
- downY = focusY
- originalOffsetX = offsetX
- originalOffsetY = offsetY
- }
-
- MotionEvent.ACTION_MOVE -> {
- offsetX = focusX - downX + originalOffsetX
- offsetY = focusY - downY + originalOffsetY
- invalidate()
- }
- }
- return true
- }
- }
多指
- package com.example.myapplication.view
-
- import android.content.Context
- import android.graphics.Canvas
- import android.graphics.Paint
- import android.graphics.Path
- import android.util.AttributeSet
- import android.util.SparseArray
- import android.view.MotionEvent
- import android.view.View
- import androidx.core.util.isEmpty
- import com.example.myapplication.dp
- class MultiTouchView3(context: Context, attrs: AttributeSet) : View(context, attrs) {
- private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
- private var paths = SparseArray<Path>()
- init {
- paint.style = Paint.Style.STROKE
- paint.strokeWidth = 4.dp
- paint.strokeCap = Paint.Cap.ROUND
- paint.strokeJoin = Paint.Join.ROUND
- }
- override fun onDraw(canvas: Canvas) {
- super.onDraw(canvas)
- for (i in 0 until paths.size()){
- val path = paths.valueAt(i)
- canvas.drawPath(path,paint)
- }
- }
- override fun onTouchEvent(event: MotionEvent): Boolean {
- when(event.actionMasked){
- MotionEvent.ACTION_DOWN,MotionEvent.ACTION_POINTER_DOWN ->{
- val actionIndex = event.actionIndex
- val path = Path()
- path.moveTo(event.getX(actionIndex),event.getY(actionIndex))
- paths.append(event.getPointerId(actionIndex),path)
- invalidate()
- }
- MotionEvent.ACTION_MOVE ->{
- if (!paths.isEmpty()){
- for (i in 0 until paths.size()){
- val pointerId = event.getPointerId(i)
- val path = paths.get(pointerId)
- path.lineTo(event.getX(i),event.getY(i))
- }
- invalidate()
- }
- }
- MotionEvent.ACTION_UP,MotionEvent.ACTION_POINTER_UP -> {
- val actionIndex = event.actionIndex
- val pointerId = event.getPointerId(actionIndex)
- paths.remove(pointerId)
- invalidate()
- }
- }
- return true
- }
- }