2020年3月13日金曜日

Drag を実装する その1 : GestureDetector なし

Drag and scale | Android Developers (MotionEventCompat を使ってたりちょっと古い)を参考に変えたもの 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 var activePointerId = INVALID_POINTER_ID private var lastTouchX = 0f private var lastTouchY = 0f private val targetView: View init { val size = (100 * resources.displayMetrics.density).toInt() targetView = View(context).apply { layoutParams = LayoutParams(size, size) setBackgroundColor(Color.RED) } addView(targetView) } override fun onTouchEvent(ev: MotionEvent): Boolean { when (ev.actionMasked) { MotionEvent.ACTION_DOWN -> { val pointerIndex = ev.actionIndex val x = ev.getX(pointerIndex) val y = ev.getY(pointerIndex) if (!(x.toInt() in 0..width && y.toInt() in 0..height)) { return false } val left = targetView.translationX val right = left + targetView.width val top = targetView.translationY val bottom = top + targetView.height if (!(x in left..right && y in top..bottom)) { return false } lastTouchX = x lastTouchY = y activePointerId = ev.getPointerId(0) } MotionEvent.ACTION_MOVE -> { if (activePointerId == INVALID_POINTER_ID) { return false } val pointerIndex = ev.findPointerIndex(activePointerId) val x = ev.getX(pointerIndex) val y = ev.getY(pointerIndex) if (!(x.toInt() in 0..width && y.toInt() in 0..height)) { return false } val diffX = x - lastTouchX val diffY = y - lastTouchY targetView.translationX += diffX targetView.translationY += diffY lastTouchX = x lastTouchY = y } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { activePointerId = INVALID_POINTER_ID } MotionEvent.ACTION_POINTER_UP -> { if (activePointerId == INVALID_POINTER_ID) { return false } val pointerIndex = ev.actionIndex if (ev.getPointerId(pointerIndex) != activePointerId) { return false } val newPointerIndex = if (pointerIndex == 0) 1 else 0 val x = ev.getX(newPointerIndex) val y = ev.getY(newPointerIndex) if (!(x.toInt() in 0..width && y.toInt() in 0..height)) { activePointerId = INVALID_POINTER_ID return false } lastTouchX = x lastTouchY = y activePointerId = ev.getPointerId(newPointerIndex) } } return true } }


0 件のコメント:

コメントを投稿