简体   繁体   English

如何为捏合手势手动创建 Android MotionEvents

[英]How to manually create Android MotionEvents for a pinch gesture

I was looking to create Android MotionEvents to simulate a pinch (scale) gesture.我一直在寻找创建 Android MotionEvents 来模拟捏合(缩放)手势。 There wasn't any good documentation, so I am adding my solution below.没有任何好的文档,所以我在下面添加我的解决方案。

Generating a MotionEvent requires a lot of parameters, so I created this method to simplify generating the events I needed (in my case, two pointer events moving toward or away from each other on the X axis:生成 MotionEvent 需要很多参数,所以我创建了这个方法来简化生成我需要的事件(在我的例子中,两个指针事件在 X 轴上相互靠近或远离:

private fun generateMotionEvent(animationStart: Long, centerX: Float, xOffset: Float, y: Float) : MotionEvent {
    val pointerProperties = Array(2) { PointerProperties() }
    pointerProperties[0].id = 0
    pointerProperties[1].id = 1
    val pointerCoords = Array(2) { MotionEvent.PointerCoords() }
    pointerCoords[0].x = centerX - xOffset
    pointerCoords[0].y = y
    pointerCoords[1].x = centerX + xOffset
    pointerCoords[1].y = y
    return MotionEvent.obtain(
        animationStart,             // downTime
        SystemClock.uptimeMillis(), // eventTime
        MotionEvent.ACTION_MOVE,    // action
        2, // pointerCount
        pointerProperties, // PointerProperties[] pointerProperties
        pointerCoords, // PointerCoords[] pointerCoords
        0,  // int metaState
        0,  // int buttonState
        1F, // float xPrecision
        1F, // float yPrecision
        0,  // int deviceId
        0,  // int edgeFlags
        0,  // int source
        0   // int flags
    )
}

I then needed a series of events to trigger a ScaleGestureDetector.然后我需要一系列事件来触发 ScaleGestureDetector。 (Two pointers down, pinching, then two pointers up) Here is a quick version of what was needed. (两个指针向下,捏合,然后两个指针向上)这是所需内容的快速版本。

Pointers down:向下指针:

val animationStart = SystemClock.uptimeMillis()

val leftFingerDownEvent = MotionEvent.obtain(animationStart, animationStart, MotionEvent.ACTION_DOWN,
    leftFinger.x, leftFinger.y, 0)
targetView.dispatchTouchEvent(leftFingerDownEvent)
val rightFingerDownAction = MotionEvent.ACTION_POINTER_DOWN or (1 shl MotionEvent.ACTION_POINTER_INDEX_SHIFT)
val rightFingerDownEvent = generateMotionEvent(animationStart, fingerX, initialFingerSpacing.toFloat(), fingerY)
rightFingerDownEvent.action = rightFingerDownAction
targetView.dispatchTouchEvent(rightFingerDownEvent)

Motion (in my case, inside an ObjectAnimator):运动(在我的例子中,在 ObjectAnimator 中):

val event = generateMotionEvent(animationStart, fingerX, fingerX - value, fingerY)
targetView.dispatchTouchEvent(event)

Pointers up:指针向上:

val rightFingerUpAction = MotionEvent.ACTION_POINTER_UP or (1 shl MotionEvent.ACTION_POINTER_INDEX_SHIFT)
val rightFingerUpEvent = generateMotionEvent(animationStart, fingerX, initialFingerSpacing.toFloat(), fingerY)
rightFingerUpEvent.action = rightFingerUpAction
audioView.dispatchTouchEvent(rightFingerUpEvent)
val leftFingerUpEvent = MotionEvent.obtain(animationStart, SystemClock.uptimeMillis(),
    MotionEvent.ACTION_UP, leftFinger.x, leftFinger.y, 0)
targetView.dispatchTouchEvent(leftFingerUpEvent)

I thought it was worth leaving this answer here for posterity, in case someone else hit a similar problem.我认为值得为后代留下这个答案,以防其他人遇到类似的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM