2020年3月16日月曜日

Drag を実装する その2 : GestureDetector

GestureDetector を使うと onScroll() で移動距離を教えてくれる。ただし、GestureDetector は ACTION_UP や ACTION_CANCEL を通知してくれないのが難点である。
  1. class SimpleDragView : FrameLayout {  
  2.   
  3.     constructor(context: Context) : super(context)  
  4.     constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)  
  5.     constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(  
  6.         context,  
  7.         attrs,  
  8.         defStyleAttr  
  9.     )  
  10.   
  11.     private val targetView: View  
  12.   
  13.     private val gestureDetector: GestureDetector  
  14.   
  15.     init {  
  16.         val size = (100 * resources.displayMetrics.density).toInt()  
  17.         targetView = View(context).apply {  
  18.             layoutParams = LayoutParams(size, size)  
  19.             setBackgroundColor(Color.RED)  
  20.         }  
  21.         addView(targetView)  
  22.   
  23.         gestureDetector =  
  24.             GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {  
  25.                 override fun onScroll(  
  26.                     e1: MotionEvent,  
  27.                     e2: MotionEvent,  
  28.                     distanceX: Float,  
  29.                     distanceY: Float  
  30.                 ): Boolean {  
  31.   
  32.                     targetView.translationX -= distanceX  
  33.                     targetView.translationY -= distanceY  
  34.   
  35.                     return true  
  36.                 }  
  37.   
  38.                 override fun onDown(e: MotionEvent): Boolean {  
  39.   
  40.                     val pointerIndex = e.actionIndex  
  41.                     val x = e.getX(pointerIndex)  
  42.                     val y = e.getY(pointerIndex)  
  43.   
  44.                     if (!(x.toInt() in 0..width && y.toInt() in 0..height)) {  
  45.                         return false  
  46.                     }  
  47.   
  48.                     val left = targetView.translationX  
  49.                     val right = left + targetView.width  
  50.                     val top = targetView.translationY  
  51.                     val bottom = top + targetView.height  
  52.   
  53.                     if (!(x in left..right && y in top..bottom)) {  
  54.                         return false  
  55.                     }  
  56.   
  57.                     return true  
  58.                 }  
  59.             })  
  60.         gestureDetector.setIsLongpressEnabled(false)  
  61.     }  
  62.   
  63.     override fun onTouchEvent(ev: MotionEvent): Boolean {  
  64.         return gestureDetector.onTouchEvent(ev) || super.onTouchEvent(ev)  
  65.     }  
  66. }  



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




0 件のコメント:

コメントを投稿