Androidのイベント処理メソッドから返されるブール値の意味は何ですか


110

Androidでは、ほとんどのイベントリスナーメソッドがブール値を返します。その真/偽の値はどういう意味ですか?それがその後の出来事に何をもたらすでしょうか?

class MyTouchListener implements OnTouchListener {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        logView.showEvent(event);
        return true;
    }
}

上記の例に関して、onTouchメソッドでtrueを返すと、すべてのタッチイベント(DOWN、UP、MOVEなど)がlogViewに従ってキャプチャされていることがわかりました。逆に、falseが返された場合、1つはDOWNイベントがキャプチャされたことです。したがって、falseを返すと、イベントの伝播が妨げられるようです。私は正しいですか?

さらに、OnGestureListenerでは、多くのメソッドもブール値を返す必要があります。同じ意味ですか?

回答:


140

イベントtrueから戻った場合ACTION_DOWN、そのジェスチャーの残りのイベントに興味があります。この場合の「ジェスチャー」とは、最終ACTION_UPまたはまでのすべてのイベントを意味しますACTION_CANCEL。イベントfalseからの復帰は、ACTION_DOWNイベントを望まないという意味であり、他のビューはそれを処理する機会があります。重複するビューがある場合、これは兄弟ビューになる可能性があります。そうでない場合、それは親にバブルアップします。


3
adamp、イベントを受信し続け、イベントを通過させる方法はありますか?
ticofab 2014年

@ticofabいいえ、現在イベントを受け取っているビューの親だけが、ジェスチャーで将来のイベントをインターセプトできます。(もちろん、親ビューでいつでも独自のリダイレクトシステムを構築できますが、何をしているのか本当にわかっているのでない限り、お勧めしません。:))
adamp

@adamp trueを返すときにonTouchが2回呼び出され、falseを返すときにのみ1回呼び出される理由は考えられません。
Bhargav Jhaveri 2014

1
@adamp:ACTION_DOWNからfalseを返していますが、ACTION_UPがトリガーされて実行されています。
Mahantesh M Ambi 2014

この返信が間違っているのでしょうか、それとも他のすべての人が間違っているのでしょうか。しかし、真実は完全に逆です。
Kai Wang


12

ブール値は、イベントが消費されるかどうかを決定します。

はい、あなたは正しいです。falseを返すと、次のリスナーがイベントを処理します。trueを返す場合、イベントはリスナーによって消費され、次のメソッドには送信されません。


2
これは誤りです。trueイベントを消費し、残りのイベントをジェスチャーで必要とすることを意味します。他のリスナー/ビューはイベントを受け取りません。false他の誰かにイベントを処理させることを意味します。ただし、実際にはそれよりも少し具体的です。私の答えを見てください。
ダンプ

それが私が言ったこととまったく同じではないのですか?
Falmarri

1
あなたが言ったことは逆です。:)
adamp

4

上記のすべての答えが正しいですが、結果は異なっているビューがある場合ですclickableclickable

、私はこのようLinearLayoutに1 Buttonと1を含んでいますTextView

<LinearLayout
    android:id="@+id/linearlayout_root"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0aa"
    android:orientation="vertical">

    <Button
        android:id="@+id/button_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="40dp"
        android:text="Button Click"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/textview_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="40dp"
        android:text="TextView Click"
        android:textSize="20sp"
        android:background="#e4e4e4"
        />

</LinearLayout>

アクティビティには、次のようなコードがあります

class MainActivity : AppCompatActivity() {
    val TAG = "TAG"

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<LinearLayout>(R.id.linearlayout_root).setOnTouchListener { v, event ->
            Log.i(TAG, "LinearLayout onTouch event " + getDisplayAction(event.action))
            false
        }

        findViewById<Button>(R.id.button_click).setOnTouchListener { v, event ->
            Log.i(TAG, "Button onTouch event " + getDisplayAction(event.action))
            false
        }

        findViewById<TextView>(R.id.textview_click).setOnTouchListener { v, event ->
            Log.i(TAG, "TextView onTouch event " + getDisplayAction(event.action))
            false
        }
    }

    private fun getDisplayAction(action: Int): String {
        return when (action) {
            MotionEvent.ACTION_DOWN -> "DOWN"
            MotionEvent.ACTION_MOVE -> "MOVE"
            MotionEvent.ACTION_UP -> "UP"
            MotionEvent.ACTION_CANCEL -> "CANCEL"
            MotionEvent.ACTION_OUTSIDE -> "OUTSIDE"
            else -> "UNKNOWN"
        }
    }
}

ケース1 Linear onTouch return **FALSE**Button onTouch return **FALSE**TextView onTouch return **FALSE**

ボタンをクリック

I/TAG: Button onTouch eventDOWN
I/TAG: Button onTouch eventMOVE
I/TAG: Button onTouch eventUP

TextViewをクリックします

TAG: TextView onTouch eventDOWN
TAG: LinearLayout onTouch eventDOWN

LinearLayoutをクリックします。

TAG: LinearLayout onTouch eventDOWN

ケース2 Linear onTouch return **FALSE**Button onTouch return **TRUE**TextView onTouch return **TRUE**

ボタンをクリック

Similar to case 1

TextViewをクリックします

TAG: TextView onTouch event DOWN
TAG: TextView onTouch event MOVE
TAG: TextView onTouch event UP

LinearLayoutをクリックします。

Similar to case 1

ケース3 Linear onTouch return **TRUE**Button onTouch return **FALSE**TextView onTouch return **FALSE**

ボタンをクリック

Similar to case 1

TextViewをクリックします

TAG: TextView onTouch event DOWN
TAG: LinearLayout onTouch event DOWN
TAG: LinearLayout onTouch event MOVE
TAG: LinearLayout onTouch event UP

LinearLayoutをクリックします。

TAG: LinearLayout onTouch event DOWN
TAG: LinearLayout onTouch event MOVE
TAG: LinearLayout onTouch event UP

注意

  • デフォルトはTextViewですnot clickable。xmlで設定android:clickable="true"した場合、または設定した場合にクリック可能になりますtextView.setOnClickListener(...)
  • デバッグevent MOVEすると、ログよりも多くを呼び出すことができます(タップ方法に基づきます)

概要

  • onTouchリターンtrueまたはビューはclickable 、ビューはすべてを受け取ります onTouchEvent
  • onTouchreturn falseand view is not clickable、view will not receive NEXT onTouchEvent(それの親はそれを受け取るかもしれません)

デモに役立つことを願っています


1
これが答えになるはずです!そのような詳細な説明をありがとう
Mysterious_android

1

私はトラブルシューティングでほぼ1日を失いましたが、それでもわかっています。trueを使用すると、onTouch関数が2回呼び出され、falseを使用すると1回呼び出されます。


その理由を教えてください。
Bhargav Jhaveri 2014

ACTION_DOWNイベントでevent.getAction()戻るfalse場合、ACTION_UPイベントはリスナーによって無視されるため、確認してください
doodeec

0

Android-documentから:

注:Androidは最初にイベントハンドラーを呼び出し、次にクラス定義から適切なデフォルトハンドラーを呼び出します。そのため、これらのイベントリスナーからtrueを返すと、他のイベントリスナーへのイベントの伝播が停止し、ビューのデフォルトのイベントハンドラーへのコールバックもブロックされます。したがって、trueを返したときにイベントを終了することを確認してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.