26
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AndroidのCustomViewでタッチ領域を円にする

Last updated at Posted at 2015-01-26

Androidでタッチ領域をカスタマイズしたい

こういう状況を想定しています。

custom view detect

こういう風に、CustomViewでのタッチ判定領域をカスタマイズするときにどうすればいいのかを調べてみた結果をまとめておきます。

円状のボタンを作った時とか、独自の形をしたViewを作った時に、タッチ領域が四角のままというのをなんとかしたいという要望が出たので作りました。(需要は少なそう)

View#dispatchTouchEventを使用する

結果として、ViewクラスにあるdispatchTouchEventをOverrideすればいいらしい。

CircleDetectView.java
public class CircleDetectView extends View {
    //... 中略

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        float touchX = event.getX(), touchY = event.getY();
        float r = getWidth() / 2;

        // 中心からタッチ点までの距離(の2乗)を計算
        // float lenght = (float)Math.pow(touchX - r, 2) + (float)Math.pow(touchY - r, 2);
        // 追記(2015/2/26):
        // 距離を測る Math.hypot という大層便利なメソッドがありました。
        double length = Math.hypot(touchX - r, touchY - r);

        // (中心からタッチ点までの距離)^2 <= (円の半径)^2
        if (length <= r * r) {
            // 円の内部
            // (superを呼び出すことによってonTouchやonClickを呼び出すようにする)
            return super.dispatchTouchEvent(event);
        } else {
            // 円の外部(falseにすると、onTouchやonClickなどが呼ばれない)
            return false;
        }
    }
}

dispatchTouchEventがタッチイベントの起点として使われてるようなので、こいつを少しいじってやれば解決するようです。

今回は円の内側をタッチ領域としたいので、タッチした点から円の中心(今回はViewの中心)までの距離が半径よりも小さくなれば円の内側をタッチしたことが表せますね。

展望

領域判定の部分をinterfaceにして、領域を自分でカスタマイズ出来るようになったらちょっとおもしろそう。
星形の判定とか、同じ円でも中心をずらして半円のタッチ領域とか、いろいろ可能性はありそうですね。

参考サイト様

Android のタッチイベントを理解する(その1)
http://blog.lciel.jp/blog/2013/12/03/android-touch-event/

26
25
0

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
26
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?