Android多点触控实现可缩放的textview

效果图

多点缩放textview.gif

代码

package com.bhb.seniorcustomview.actionMask

import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import android.view.MotionEvent
import android.widget.TextView

/**
 *  create by BHB on 9/6/21
 */

class TouchScaleTextView : TextView{

    var mode = 0
    var mOldDist = 0f
    var mTextSize = 0f

    constructor(context: Context):super(context ){
    }
    constructor(context: Context, attributes: AttributeSet):super(context , attributes){
    }
    constructor(context: Context, attributes: AttributeSet, defStyle : Int):super(context , attributes , defStyle){
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if(mTextSize == 0f){
            mTextSize = textSize

        }
        when(event!!.actionMasked){
            MotionEvent.ACTION_DOWN ->{
                mOldDist = 0f
                mode = 1
            }
            MotionEvent.ACTION_UP ->{
                mode = 0
            }
            MotionEvent.ACTION_POINTER_UP ->{
                mode -= 1
            }
            MotionEvent.ACTION_POINTER_DOWN ->{
                mOldDist = spacing(event)
                mode += 1
            }
            MotionEvent.ACTION_MOVE ->{
                if(mode >= 2){
                    var newDist = spacing(event)
                    if(Math.abs(newDist - mOldDist) > 50){
                        zoom(newDist/mOldDist)
                        mOldDist = newDist
                    }
                }
            }
        }
        return true
    }

    fun zoom(f:Float){
        mTextSize *= f
        setTextSize(TypedValue.COMPLEX_UNIT_PX , mTextSize)
    }

    fun spacing(event: MotionEvent):Float{
        var x = event.getX(0) - event.getX(1)
        var y = event.getX(0) - event.getX(1)
        return Math.sqrt((x*x + y*y).toDouble()).toFloat()
    }


}

xml使用




    



代码讲解

我们可以看到 这里我们其实只处理了 ontouchevent事件
和平常使用的 event.action 不同 这里使用的是 event.actionMasked
一个event事件中其实可以包含多个point 对象

MotionEvent函数 含义
int getActionIndex() 获取当前触摸事件的index 在move事件中无效
int getPointerId(int pointerIndex) 根据传入的index获取对应pooint 的id
int findPointerIndex(int pointerId) 根据传入的id获取对应point的index
int getPointerCount() 获取当前事件包含的point 个数
float getX(int pointerIndex) 获取第index个point的 x值
float getY(int pointerIndex) 获取第index个point的 y值
actionMasked 匹配的值 含义
ACTION_DOWN 第一个手指按下
ACTION_UP 最后一个手指放开
ACTION_POINTER_UP 手指放开但不是最后一个
ACTION_POINTER_DOWN 手指按下 但不是第一个
ACTION_MOVE 手指移动

代码中我们声明一个变量 用于计算当前按下的手指个数
手指按下数量+1 手指放开 数量-1
并在move事件中 判断当前按下的手指数量是>=2 有多个手指按下时才计算缩放
通过float getX(int pointerIndex) 和 float getY(int pointerIndex)
在ACTION_POINTER_DOWN事件中得到初始的值 在move事件中得到 第一个point和第二个point x轴和y轴的偏移量 两者的比例即是缩放的比例

多点触控需要硬件支持 检测方法

  fun isSupportMultiTouch(context: Context):Boolean{
        var packageManager  = context.packageManager
        return packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)
    }

你可能感兴趣的:(Android多点触控实现可缩放的textview)