日常开发中自定义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)
}
}
}