LoginSignup
1

More than 3 years have passed since last update.

Android API29未満で getRawX(index)をする(回転、拡大、縮小に対応)

Posted at

getX()とgetRawX()

MotionEventにはgetX()とgetRawX()という異なるメソッドがあります。
(もちろん同様にy座標に関するメソッドもあります)

この2つのメソッドの違いは、getX()はEventの対象となるViewのローカル座標、getRawX()はスクリーン上の座標を取得するという点になります。

getRawX()とgetRawX(index)

API29からgetRaw(index)というメソッドが追加されました。
MotionEventではタッチされている座標(pointer)が複数ある場合があり、indexを指定することでpointerごとの座標を取得することができます。

しかし、getRawX(index)はAPI29から追加されたメソッドのため、API29未満では自分で計算を行うことになります。
API29未満にもgetX(index)というメソッドがあります、これは指定したindexのpointerのローカル座標を取得するメソッドです。このメソッドを利用して計算をします。

ローカル座標からスクリーン座標への変換

具体的なコードは以下になります。
Viewが回転、拡大、縮小していた場合にも正しい座標が取得できるようになっています。
回転、拡大、縮小が不要な場合には該当のコードを削除してください。

private fun getRawPoint(view: View, event: MotionEvent, index: Int): PointF {
    val location = intArrayOf(0, 0)
    view.getLocationOnScreen(location)
    var x = event.getX(index) * view.scaleX
    var y = event.getY(index) * view.scaleY
    var angle = Math.toDegrees(atan2(y.toDouble(), x.toDouble()))
    angle += view.rotation.toDouble()
    val length = hypot(x, y)
    x = (length * cos(Math.toRadians(angle))).toFloat() + location[0]
    y = (length * sin(Math.toRadians(angle))).toFloat() + location[1]
    return PointF(x, y)
}

scaleが変更されていた場合を考慮し、x, yの値にscaleをかけています。
また、回転していた場合を考慮し、アークタンジェントを求めるatan2(y, x)を利用して座標から角度を求めrotationと合計しています。
解説のため下図を用意しました。
rotationでαの角度、atan2(y, x)でβの角度を求めています。
lengthが三角関数の斜辺となりα + βが三角関数のθとなるのであとはsin、cosで座標が求められますね。

スクリーンショット 2021-03-08 10.35.06.png

API29未満でMotionEventからスクリーン座標を取得したいときにお使いください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1