package com.wuhongru.workman.myView
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.widget.OverScroller
import androidx.constraintlayout.motion.widget.MotionInterpolator
import androidx.core.view.children
import kotlin.math.abs
import kotlin.math.min
class TwoPager(context: Context, attrs: AttributeSet) : ViewGroup(context, attrs) {
private val viewConfiguration = ViewConfiguration.get(context)
//Distance in pixels a touch can wander before we think the user is scrolling a full page
//在我们认为用户滚动整个页面之前,触摸可能会偏离的距离(以像素为单位)
private val pagingSlop = viewConfiguration.scaledPagingTouchSlop
//Minimum velocity to initiate a fling, as measured in pixels per second.
//启动投掷的最小速度,以每秒像素数为单位。
private val minVelocity = viewConfiguration.scaledMinimumFlingVelocity
//启动投掷的最大速度,以每秒像素数为单位。
private val maxVelocity = viewConfiguration.scaledMaximumFlingVelocity
private val velocityTracker = VelocityTracker.obtain()
private var isScrolling = false
private var downX = 0f
private var downY = 0f
private var downScrollX = 0f
private val overScroller = OverScroller(context)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
//给所有子view边界
measureChildren(widthMeasureSpec, heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var childLeft = 0
val childTop = 0
var childRight = width
val childBottom = height
for (child in children) {
child.layout(childLeft, childTop, childRight, childBottom)
childLeft += width
childRight += width
}
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
if(event.actionMasked == MotionEvent.ACTION_DOWN){
Log.e("wuhongru",scrollX.toString())
velocityTracker.clear()
}
velocityTracker.addMovement(event)
var result = false
when(event.actionMasked){
MotionEvent.ACTION_DOWN->{
downX = event.x
downY = event.y
isScrolling = false
downScrollX = scrollX.toFloat()
}
MotionEvent.ACTION_MOVE->{
if(!isScrolling){
val dx = event.x-downX
if (abs(dx)>pagingSlop){
isScrolling = true
parent.requestDisallowInterceptTouchEvent(true)
result = true
}
}
}
}
return result
}
override fun onTouchEvent(event: MotionEvent): Boolean {
if(event.actionMasked == MotionEvent.ACTION_DOWN){
velocityTracker.clear()
}
velocityTracker.addMovement(event)
when(event.actionMasked){
MotionEvent.ACTION_DOWN->{
downX = event.x
downY = event.y
downScrollX = scrollX.toFloat()
}
MotionEvent.ACTION_MOVE->{
val dx = (downScrollX-(event.x-downX)).toInt()
.coerceAtLeast(0)
.coerceAtMost(width)
scrollTo(dx,0)
}
MotionEvent.ACTION_UP->{
velocityTracker.computeCurrentVelocity(1000,maxVelocity.toFloat())
val vx = velocityTracker.xVelocity
val scrollX = scrollX
val targetPage = if(abs(vx)< minVelocity){
if(scrollX>width/2) 1 else 0
}else{
if(vx<0) 1 else 0
}
val scrollDistance = if(targetPage == 1) width-scrollX else -scrollX
overScroller.startScroll(scrollX,0,scrollDistance,0)
postInvalidateOnAnimation()
}
}
return true
}
// 每次调用draw的时候会被调用
override fun computeScroll() {
if (overScroller.computeScrollOffset()){
scrollTo(overScroller.currX,overScroller.currY)
postInvalidateOnAnimation()
}
}
}
上一篇

drag
2023-01-12
下一篇

touchSlop
2023-01-10