2020年5月21日木曜日

VelocityTracker の使い方

VelocityTracker はタッチイベントの速度計算を簡単にするためのクラスです。Fling など速度がジェスチャーの構成要素になっているものに対して便利です。

VelocityTracker.obtain() でインスタンスを取得します。
addMovement(ev) で MotionEvent を追加し、速度を取得するときは computeCurrentVelocity(int units) または computeCurrentVelocity(int units, float maxVelocity) を呼んだ後に getXVelocity(), getYVelocity() を呼びます。
obtain() で取得したインスタンスは不要になった時点で recycle() を呼びましょう。

computeCurrentVelocity() で maxVelocity を渡さない場合は Float.MAX_VALUE が使われます。 computeCurrentVelocity() で渡す units は getXVelocity(), getYVelocity() で取得する velocity の単位になります。1 を指定した場合は pixels per millisecond、1000 を渡した場合は pixels per second になります。 class SimpleDragView : FrameLayout { constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( context, attrs, defStyleAttr ) private val targetView: View private var velocityTracker: VelocityTracker? = null init { val size = (100 * resources.displayMetrics.density).toInt() targetView = View(context).apply { layoutParams = LayoutParams(size, size).apply { gravity = Gravity.CENTER } setBackgroundColor(Color.RED) } addView(targetView) } private var lastVelocityX = 0f private var lastVelocityY = 0f override fun onTouchEvent(ev: MotionEvent): Boolean { when (ev.actionMasked) { MotionEvent.ACTION_DOWN -> { velocityTracker?.clear() velocityTracker = velocityTracker ?: VelocityTracker.obtain() velocityTracker?.addMovement(ev) } MotionEvent.ACTION_MOVE -> { velocityTracker?.let { it.addMovement(ev) val pointerId: Int = ev.getPointerId(ev.actionIndex) it.computeCurrentVelocity(1000) lastVelocityX = it.getXVelocity(pointerId) lastVelocityY = it.getYVelocity(pointerId) } } MotionEvent.ACTION_UP -> { velocityTracker?.let { ObjectAnimator .ofPropertyValuesHolder( targetView, PropertyValuesHolder.ofFloat( View.TRANSLATION_X, lastVelocityX / 4 ), PropertyValuesHolder.ofFloat( View.TRANSLATION_Y, lastVelocityY / 4 ) ) .apply { addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { super.onAnimationEnd(animation) targetView.translationX = 0f targetView.translationY = 0f } }) } .setDuration(500) .start() } velocityTracker?.recycle() velocityTracker = null } MotionEvent.ACTION_CANCEL -> { velocityTracker?.recycle() velocityTracker = null } } return true } }


0 件のコメント:

コメントを投稿