2020年3月16日月曜日

Drag を実装する その2 : GestureDetector

GestureDetector を使うと onScroll() で移動距離を教えてくれる。ただし、GestureDetector は ACTION_UP や ACTION_CANCEL を通知してくれないのが難点である。 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 val gestureDetector: GestureDetector init { val size = (100 * resources.displayMetrics.density).toInt() targetView = View(context).apply { layoutParams = LayoutParams(size, size) setBackgroundColor(Color.RED) } addView(targetView) gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() { override fun onScroll( e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float ): Boolean { targetView.translationX -= distanceX targetView.translationY -= distanceY return true } override fun onDown(e: MotionEvent): Boolean { val pointerIndex = e.actionIndex val x = e.getX(pointerIndex) val y = e.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 } return true } }) gestureDetector.setIsLongpressEnabled(false) } override fun onTouchEvent(ev: MotionEvent): Boolean { return gestureDetector.onTouchEvent(ev) || super.onTouchEvent(ev) } }


setIsLongpressEnabled(false) しないと下のように LongPress 判定されたときに onScroll() が呼ばれない。




0 件のコメント:

コメントを投稿