自定义ViewGroup触摸事件
class MyGroupView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {
<pre><code>val overScroller = OverScroller(context)
val velocityTracker: VelocityTracker = VelocityTracker.obtain().apply {
computeCurrentVelocity(1000)
} //测量惯性速度
val viewConfiguration = ViewConfiguration.get(context) //获取Android通用配置
val maxVelocityTracker = viewConfiguration.scaledMaximumFlingVelocity
val minVelocityTracker = viewConfiguration.scaledMinimumFlingVelocity
val pagingSlop = viewConfiguration.scaledPagingTouchSlop //最小移动距离
var downX = 0f
var downY = 0f
var scroller = false
var downScrollX = 0
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
measureChildren(widthMeasureSpec, heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
val child1 = getChildAt(0)
child1.layout(l, t, width, height)
val child2 = getChildAt(1)
child2.layout(l + width, t, l + 2 * width, height)
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
velocityTracker.addMovement(ev)
var result = false
when(ev.actionMasked) {
MotionEvent.ACTION_DOWN -> {
velocityTracker.clear()
scroller = false
downX = ev.x
downY = ev.y
}
MotionEvent.ACTION_MOVE -> {
val dx = ev.x - downX
if (abs(dx) > pagingSlop) {
result = true
scroller = true
parent.requestDisallowInterceptTouchEvent(true) // 请求父类不拦截
}
}
}
return result
}
override fun onTouchEvent(event: MotionEvent): Boolean {
velocityTracker.addMovement(event)
when(event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
velocityTracker.clear()
downX = event.x
downY = event.y
downScrollX = scrollX //当前view移动的距离
}
MotionEvent.ACTION_MOVE -> {
val dx = (downX - event.x + downScrollX).toInt().coerceAtLeast(0).coerceAtMost(width)
//手指移动的方向应该和view移动的方向相反
scrollTo(dx,0) //移动到dx楚
}
MotionEvent.ACTION_UP -> {
velocityTracker.computeCurrentVelocity(1000,maxVelocityTracker.toFloat())
var distance = 0
distance = if (scrollX > width/2) {
width - scrollX
} else {
- scrollX
}
if (abs(velocityTracker.xVelocity) > minVelocityTracker) {
distance = if (velocityTracker.xVelocity > 0) {
- scrollX
} else {
width - scrollX
}
}
overScroller.startScroll(scrollX,0,distance,0)
//由scrollx ,0 移动到distance,0处,需要重复调用
ViewCompat.postInvalidateOnAnimation(this)
}
}
return true
}
override fun computeScroll() {
if (overScroller.computeScrollOffset()) {
scrollTo(overScroller.currX,overScroller.currY) //
ViewCompat.postInvalidateOnAnimation(this)
}
super.computeScroll()
}
}
评论区