Android 自定义View 监听 手势事件相关知识点梳理

日常开发中自定义view经常会用到单击、双击、滑动,双指缩放等常用手势操作,下边介绍通过继承类实现监听手势的案例

1.ScaleGestureDetector.OnScaleGestureListener :双指缩放手势,通过继承ScaleGestureDetector.OnScaleGestureListener实现获取缩放值

2.SimpleOnGestureListener() :点击、双击、长按、滑动等手势通过监听 SimpleOnGestureListener() 来实现

下面示例详细展示了监听方法与获取数值的方式


import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.view.View

/**
     * 自定义视图类的构造函数。
     *
     * @param context 上下文对象,不能为空。
     * @param attrs 属性集合,可以为 null。
     */
    class MyThouchView : View {

        constructor(context: Context) : this(context, null) {
        }

        constructor(context: Context, attrs: AttributeSet?) : this(context, attrs,0) {
        }

        constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
            context,
            attrs,
            defStyleAttr
        ) {
            init(context)

        }

        private var gestureDetector : GestureDetector? = null //控制单机双击事件
        private var scaleGestureDetector : ScaleGestureDetector? = null


        private fun init(context: Context) {
            gestureDetector = GestureDetector(context,MySimpleOnGestureListener())

            //scaleGestureDetector = new ScaleGestureDetector(context, new PhotoScaleGestureListener());

           scaleGestureDetector = ScaleGestureDetector(context,MyOnScaleGestureListener())
        }


        override fun draw(canvas: Canvas) {
            super.draw(canvas)

            val paint = Paint()
            paint.color = Color.rgb(255,220,220)

            canvas.drawRect(0F,0F, width.toFloat(),height.toFloat(),paint)
         }


        @SuppressLint("ClickableViewAccessibility")
        override fun onTouchEvent(event: MotionEvent?): Boolean {
            var result = true
            if (event != null) {
                result = scaleGestureDetector?.onTouchEvent(event)!!
                if (!scaleGestureDetector?.isInProgress!!) {
                    result = gestureDetector?.onTouchEvent(event)!!
                }
            }

            return result
        }

    class  MyOnScaleGestureListener : ScaleGestureDetector.OnScaleGestureListener {
        /**
         * 当缩放手势被检测到时调用的方法
         * 该方法处理缩放手势,根据当前缩放状态和用户手势调整缩放级别
         *
         * @param detector 缩放手势检测器,用于获取缩放相关的数据
         * @return 返回true表示事件被处理,false表示事件未被处理
         */
        override fun onScale(p0: ScaleGestureDetector): Boolean {
            Log.i(TAG, "双指缩放 onScale: ${p0.scaleFactor}" )
            return false
        }
        /**
         * 当缩放手势开始时调用的方法
         *
         * @param detector 缩放手势检测器,用于获取缩放事件的相关信息
         * @return 始终返回true,表示始终处理缩放事件
         * <p>
         * 该方法的主要作用是在缩放手势开始时初始化缩放比例
         * 它通过将当前缩放比例赋值给初始缩放比例变量initScale来实现
         * 这样做是为了确保缩放操作从当前视图的缩放状态开始
         */
        override fun onScaleBegin(p0: ScaleGestureDetector): Boolean {
            return true
        }

        override fun onScaleEnd(p0: ScaleGestureDetector) {
        }
    }

    companion object{
        const val TAG = "aShuai"
    }

        class MySimpleOnGestureListener : SimpleOnGestureListener() {

            //单击时触发或者双击时第一次点击时出发
            override fun onSingleTapUp(e: MotionEvent): Boolean {

                Log.i(TAG, "单击 onSingleTapUp: x ${e.x}  y ${e.y}")
                return super.onSingleTapUp(e)
            }

            //长按300ms触发
            override fun onLongPress(e: MotionEvent) {
                super.onLongPress(e)
                Log.i(TAG, "长按 onLongPress: x ${e.x}  y ${e.y}")
            }

            //滑动时触发
            override fun onScroll(
                e1: MotionEvent?,
                e2: MotionEvent,
                distanceX: Float,
                distanceY: Float
            ): Boolean {
                Log.i(TAG, "滑动 onScroll: distanceX $distanceX distanceY $distanceY")
                return super.onScroll(e1, e2, distanceX, distanceY)
            }

            //快速滑动触发 实现惯性滑动效果
            override fun onFling(
                e1: MotionEvent?,
                e2: MotionEvent,
                velocityX: Float,
                velocityY: Float
            ): Boolean {

                Log.i(TAG, "重力 onScroll: velocityX $velocityX distanceY $velocityX")

                return super.onFling(e1, e2, velocityX, velocityY)


            }

            //延时100ms触发
            override fun onShowPress(e: MotionEvent) {
                Log.i(TAG, "单击延时100 onShowPress: x ${e.x}  y ${e.y}")

                super.onShowPress(e)
            }

            //只需要关注返回值,返回为true时其余方法才会执行,返回false其余方法不执行
            override fun onDown(e: MotionEvent): Boolean {

                return true
            }

            //双击事件检测
            override fun onDoubleTap(e: MotionEvent): Boolean {
                Log.i(TAG, "双击 onDoubleTap: x ${e.x}  y ${e.y}")
                return super.onDoubleTap(e)
            }

            //双击的第二个down move up 都触发
            override fun onDoubleTapEvent(e: MotionEvent): Boolean {
                Log.i(TAG, "双击的第二个down move up 都触发 onDoubleTapEvent: x ${e.x}  y ${e.y}")

                return super.onDoubleTapEvent(e)
            }
            // 单击按下时触发,双击时不触发,down,up时都可能触发
            // 延时300ms触发TAP事件
            // 300ms以内抬手 -- 才会触发TAP -- onSingleTapConfirmed
            // 300ms 以后抬手 --- 不是双击不是长按,则触发
            override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
                return super.onSingleTapConfirmed(e)
            }

        }

    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值