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를 반환하면 DOWN 이벤트가 캡처 된 것입니다. 따라서 false를 반환하면 이벤트가 전파되지 않는 것 같습니다. 나 맞아 ?

또한 OnGestureListener 에서 많은 메서드가 부울 값도 반환해야합니다. 그들은 같은 의미를 가지고 있습니까?

답변:


140

이벤트 true에서 돌아 오면 ACTION_DOWN해당 제스처의 나머지 이벤트에 관심이 있습니다. 이 경우 '제스처'는 결승전 ACTION_UP또는 까지의 모든 이벤트를 의미합니다 ACTION_CANCEL. 에서 돌아온다 false는 것은 ACTION_DOWN이벤트를 원하지 않는다는 것을 의미하며 다른 뷰는 이벤트를 처리 할 기회를 갖게됩니다. 겹치는 뷰가있는 경우 형제 뷰가 될 수 있습니다. 그렇지 않으면 부모에게 버블 링됩니다.


3
adamp, 이벤트를 계속 수신하고 이벤트를 통과시키는 방법이 있습니까?
ticofab

@ticofab 아니요, 현재 이벤트를 수신하는 뷰의 부모 만 제스처에서 향후 이벤트를 가로 챌 수 있습니다. (물론 부모보기에서 항상 자신의 리디렉션 시스템을 구축 할 수 있지만 실제로 수행중인 작업을 알지 않는 한 권장하지 않습니다. :))
adamp 2014 년

@adamp true를 반환 할 때 onTouch가 2 번 호출되고 false를 반환 할 때만 1 번 호출되는 이유를 생각할 수 없습니다.
Bhargav Jhaveri

1
@adamp : ACTION_DOWN에서 false를 반환하지만 ACTION_UP이 트리거되고 실행됩니다.
Mahantesh M Ambi 2014 년

내가이 답장을 잘못 받거나 다른 사람들이 ...이 답장은 true 반환은 힘든 이벤트가 소비되지 않는다는 것을 의미한다고 말했습니다. 그러나 진실은 완전히 반대입니다.
Kai Wang


12

부울 값은 이벤트 소비 여부를 결정합니다.

네 맞습니다. false를 반환하면 다음 리스너가 이벤트를 처리합니다. true를 반환하면 이벤트가 리스너에 의해 소비되고 다음 메서드로 전송되지 않습니다.


2
이것은 거짓입니다. true이벤트를 소비하고 제스처의 나머지 이벤트를 원한다는 의미입니다. 다른 리스너 / 뷰는 이벤트를 수신하지 않습니다. false다른 사람이 이벤트를 처리하게한다는 의미입니다. 사실 그보다 좀 더 구체적입니다. 내 대답을 참조하십시오.
adamp

내가 말한 것이 정확히 어떻게되지 않습니까?
Falmarri

1
당신이 말한 것은 반대입니다. :)
adamp

4

위의 모든 대답은 정확하지만 결과는 View가 clickable있는지 여부입니다.clickable

, 나는 이것 과 같은 LinearLayout1 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우리가 설정 한 경우이 클릭 될 것입니다, android:clickable="true"XML로 또는 우리가 설정 한 경우textView.setOnClickListener(...)
  • 디버그 할 때 event MOVE내 로그보다 더 많이 호출 할 수 있습니다 (탭하는 방법에 따라 다름)

요약

  • onTouch반환 true또는보기는 clickable ,보기는 모두 수신 합니다. onTouchEvent
  • onTouchreturn false및 view is not clickable, view will not receive NEXT onTouchEvent (it 's parent may receive it)

데모가 도움이
되기를 바랍니다.


1
이것이 답이되어야합니다! 이러한 상세한 설명에 감사드립니다
Mysterious_android

1

나는 문제 해결에서 거의 하루를 잃었지만 여전히 내 onTouch 기능이 true를 사용할 때 2 번, false를 사용할 때 1 번 호출된다는 것을 알았습니다.


이유를 알 수 있습니까?
Bhargav Jhaveri

ACTION_DOWN 이벤트에서 event.getAction()리턴하면 false리스너가 ACTION_UP 이벤트를 무시 하므로 확인하십시오
doodeec

0

에서 안드로이드 문서 :

참고 : 안드로이드 먼저 다음 클래스 정의의 두 번째에서 적절한 기본 핸들러를 이벤트 핸들러를 호출합니다. 따라서 이러한 이벤트 리스너에서 true를 반환하면 다른 이벤트 리스너로의 이벤트 전파가 중지되고 뷰의 기본 이벤트 핸들러에 대한 콜백도 차단됩니다. 따라서 true를 반환하면 이벤트를 종료해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.