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 件のコメント:
コメントを投稿