LoginSignup
6
1

More than 1 year has passed since last update.

Custom view XxxView overrides onTouchEvent but not performClick って怒られるケースについて

Last updated at Posted at 2021-07-20

概要

custom view を作成した際に、onTouchEvent() をオーバーライドしたが performClick()
をオーバーライドしていない場合に、以下のような警告が表示されます。1

Custom view XxxView overrides onTouchEvent but not performClick

performClick() について

まずは performClick() から読み解いてみようと思います。

◆ javadoc

Call this view's OnClickListener, if it is defined. Performs all normal actions associated with clicking: reporting accessibility event, playing a sound, etc.

ざっくりこんな感じですね。

  1. OnClickListener が定義されていればそれを呼び出す。
  2. クリックに関連するすべての通常の処理(accessibility event の報告や音声再生など)を実行する。

◆ 解釈

これを言い換えると、

  • クリック時の処理は OnClickListener に含まれる。
  • クリックに関連する OnClickListener 以外の処理performClick() に含まれる。

のようなことが言えると思います。

別の見方をすると、

  • custom view の外部から動的に設定される機能は OnClickListener で実行される。
  • custom view として固定のクリック音やクリック時のUI効果、デザイン上の決まり事である accessibility event の報告、などは performClick() 上で実行される。

とも言えそうです。

◆ Viewのコード

View#performClick() のコードでは

li.mOnClickListener.onClick(this)

のように OnClickListener の処理が呼び出され、

sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED

のように accessibility 系のコードも呼び出されているということがわかります。

ということで、performClick() を叩けば OnClickListener やら accessibility 系などすべて含んだクリック処理を行ってくれるってことですね。

◆ performClick() まとめ

クリック処理は、常に performClick() 経由で実行しましょう。

onTouchEvent() について

◆ javadoc

以下が onTouchEvent() の javadoc の内容。

Implement this method to handle touch screen motion events.

If this method is used to detect click actions, it is recommended that the actions be performed by implementing and calling performClick(). This will ensure consistent system behavior, including:

  ・obeying click sound preferences
  ・dispatching OnClickListener calls
  ・handling ACTION_CLICK when accessibility features are enabled

第一パラグラフは普通にタッチイベントを扱うという話。

第二パラグラフの2文目以降は performClick() の話で、既に前項で扱った話。

ということで、重要なのは残った以下の文章。

If this method is used to detect click actions, it is recommended that the actions be performed by implementing and calling performClick().

『このメソッドがクリック処理を検出するために使われるのであれば、performClick() を実装してそれを呼び出すことを推奨する』ということですが、逆を言えば、クリック処理を検出するために使われない場合には performClick() を実装して呼び出す必要はないという事になります。

◆ 補足

補足ですが、Accessibility 系のオプションを有効にしている場合など、タッチ関連の通知経路が変わることがあります。

具体的な例としては、普段は onTouchEvent() にてクリックの判断をしている場合に、端末の TalkBack を on にしていると、Accessibility 系の仕組み経由でクリックの判断が行われるため、onTouchEvent() が発生せずにいきなり performClick() が呼び出されることがあり、その場合は onTouchEvent() 内部に書かれた処理は一切実行されません

まとめ

Custom view XxxView overrides onTouchEvent but not performClick って怒られるケースについてという文脈でまとめると、以下のようになるのかなと思います:

  • onTouchEvent() がクリック処理を検出するために使われない場合
    • performClick() を実装して呼び出す必要はない。← 警告を suppress しちゃってOKだと思われ。
  • onTouchEvent() がクリック処理を検出するために使われる場合
    • クリックを検出した箇所で、クリックに関する処理はすべて performClick() に丸投げしましょう。2

以上。


  1. クラス名が XxxView の場合。 

  2. クリックに関する処理が onTouchEvent() に含まれている場合、performClick() 経由ではその処理が実行されない。 

6
1
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
6
1