RegionとPathを用いた特定の部分のTouchEventの取り方
前回書いたViewの記事の補足を少し。
なんか日本語の記事が見つからなかったので書いちゃう。
TouchEventの制御
そもそもViewのonTouchEventが呼ばれる時はpaddingやTouchDelegateをしない限り四角いViewを触った時に呼ばれるはずです。
例えば、上のようなViewがあるとして、望まれる挙動は空白の白い部分にはClickListenerを付けず、六角形の内部のみClickListenerを付けイベントを飛ばしたいと考えると思います。
そんな時役に立つのがRegionでした。
IngressAchievements/AchievementView.java at develop · amyu/IngressAchievements · GitHub
このViewを見てもらえればさくっと伝わるんですが、
/** * Pathを引きながらRegionにいろいろとセットする処理 */ for (int i = 0; i < VERTEX_NUM + 1; i++) { double cos = Math.cos(Math.toRadians(60 * i + 30)); double sin = Math.sin(Math.toRadians(60 * i + 30)); double innerX = centerX + radius * cos; double innerY = centerY + radius * sin; mInnerPath.lineTo((float) innerX, (float) innerY); } mRectF.setEmpty(); //RectFに対してPathの外枠の座標をセットする mInnerPath.computeBounds(mRectF, true); mRegion.setEmpty(); mClipRegion.setEmpty(); //ClipとなるRegionに外枠の座標をセットしたRectFをセットする mClipRegion.set((int) mRectF.left, (int) mRectF.top, (int) mRectF.right, (int) mRectF.bottom); //Regionに対してPathとClipとなるRegionをセットする mRegion.setPath(mInnerPath, mClipRegion);
と言った感じでRegionをセットしていきます。
続いてonTouchEvent内での処理。
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //Regionに触られた部分の座標が含まれているか if (mRegion.contains((int) event.getX(), (int) event.getY())) { if (mOnClickListener == null) { return true; } //何事もなかったらイベントを飛ばしてあげる mOnClickListener.onClick(this); } break; } return false; }
と言った感じで実装できます。
最後に
Unityに浮気したい。
ではではー