Android ViewGroup 浅析一

measureChildren(widthMeasureSpec, heightMeasureSpec) 将子View宽高设为同等大小
parent.requestDisallowInterceptTouchEvent(true) 当前若是滑动控件,且拦截子View,除了子View cancel,还要通知上一级View不再拦截,如果在滑动控件,触摸到子View则父View会收到InterTouch,子View收到TouchDown,而父View收不到TouchDown,scrollTo参数是相反
.coerceAtLeast(0) 上限
.coerceAtMost(width)下限
VelocityTracker 记速器

code 

package com.example.myapplication.view

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.widget.OverScroller
import androidx.core.view.children
import kotlin.math.abs

class TwoPager(context: Context, attrs: AttributeSet) : ViewGroup(context, attrs) {
    var downX = 0f
    var downY = 0f
    var downScrollX = 0f
    var scrolling = false
    var overScroller: OverScroller = OverScroller(context)
    var viewConfiuration = ViewConfiguration.get(context)
    var velocityTracker = VelocityTracker.obtain()
    var minVelocity = viewConfiuration.scaledMinimumFlingVelocity //最小快滑
    var maxVelocity = viewConfiuration.scaledMaximumFlingVelocity //最大快滑
    var pagingSlop = viewConfiuration.scaledPagingTouchSlop

    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) {
        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 onInterceptHoverEvent(event: MotionEvent): Boolean {
        if (event.actionMasked == MotionEvent.ACTION_DOWN) {
            velocityTracker.clear()
        }
        velocityTracker.addMovement(event)
        var result = false
        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                scrolling = false
                downX = event.x
                downY = event.y
                downScrollX = scrollX.toFloat()

            }
            MotionEvent.ACTION_MOVE -> if (!scrolling) {
                val dx = downX - event.x
                if (abs(dx) > pagingSlop) {
                    scrolling = 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 = (downX - event.x + downScrollX).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(getScrollX(), 0, scrollDistance, 0) //给一个位置,然后自动计算
                postInvalidateOnAnimation()
            }
        }
        return true
    }

    //draw调用 这个也会调用
    override fun computeScroll() {
        if (overScroller.computeScrollOffset()) {
            scrollTo(overScroller.currX, overScroller.currY)
            postInvalidateOnAnimation()
        }
    }
}

你可能感兴趣的:(android)