自定义ViewGroup触摸事件

class MyGroupView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {

    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()
    }
}
posted @ 2021-07-02 09:32  c-若曦  阅读(81)  评论(0)    收藏  举报