双击事件,以及惯性滑动
package com.example.rx_demo
<p>import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.OverScroller
import android.widget.Toast
import androidx.core.view.ViewCompat
import kotlin.math.min</p>
<p>class MyView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr), GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener, Runnable {
val paint = Paint().apply {
color = Color.YELLOW
}
val rect = Rect(0, 0, 100f.dp.toInt(), 100f.dp.toInt())
var offsetX = 0f
var offsetY = 0f
val gestrueDetector = GestureDetector(context, this)
<strong>//gestrueDetector 相当与一个外挂的事件处理器,可以将事件进一步分类</strong></p>
<pre><code>val overScroller = OverScroller(context)
**// 滑动处理,拥有惯性滑动方法,Scroller中的惯性滑动是从0开始的,不适合这个场景**
override fun onDraw(canvas: Canvas) {
canvas.translate(offsetX, offsetY)
canvas.drawRect(rect, paint)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
return gestrueDetector.onTouchEvent(event) **//把事件交给 gestrueDetector**
}
override fun onDown(e: MotionEvent?): Boolean {
return true **// 拿到事件,并且消费事件**
}
override fun onShowPress(e: MotionEvent?) {
// 显示按下状态
}
override fun onSingleTapUp(e: MotionEvent?): Boolean {
**//单次抬起**
return true
}
override fun onScroll(
e1: MotionEvent?,
e2: MotionEvent?,
distanceX: Float,
distanceY: Float
): Boolean {
**// 处理move事件**
offsetX += -distanceX
offsetY += -distanceY
**//disX 的值是 前一个点位置 - 后一个点位置**
offsetX = Math.min(offsetX, width.toFloat() - 100f.dp)
offsetX = Math.max(offsetX, 0f)
offsetY = Math.min(offsetY, height.toFloat() - 100f.dp)
offsetY = Math.max(offsetY, 0f)
invalidate()
return true
}
override fun onLongPress(e: MotionEvent?) {
**// 监听长按事件**
}
override fun onFling(
e1: MotionEvent?,
e2: MotionEvent?,
velocityX: Float,
velocityY: Float
): Boolean {
overScroller.fling(
offsetX.toInt(), offsetY.toInt(), velocityX.toInt(), velocityY.toInt(), 0,
(width.toFloat() - 100f.dp).toInt(), 0, (height.toFloat() - 100f.dp).toInt()
, 50f.dp.toInt(), 50f.dp.toInt()
)**//计算个个参数值**
ViewCompat.postOnAnimation(this,this) **//下一帧执行 run方法**
return true
**//处理惯性滑动**
}
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
return true
**//抬起事件,会处理双击事件,如果触发了双击事件则不调用该事件**
}
override fun onDoubleTap(e: MotionEvent?): Boolean {
Toast.makeText(context, "我双击了", Toast.LENGTH_LONG).show()
return true
**//双击事件,第二次按下触发该事件**
}
override fun onDoubleTapEvent(e: MotionEvent?): Boolean {
return true
**// 双击事件后续事件**
}
override fun run() {
if (overScroller.computeScrollOffset() ) {
offsetX = overScroller.currX.toFloat()
offsetY = overScroller.currY.toFloat()
invalidate()
**//这一帧惯性滑动已经更新**
ViewCompat.postOnAnimation(this,this)
}
}
}
评论区