onTouchEvent()에서 return true vs return false 차이안드로이드에서 onTouchEvent() 메서드에서 true 또는 false를 반환하는 것은 이벤트의 소비 여부를 결정합니다.
| 반환 값 | 의미 | 이벤트 전달 여부 |
|---|---|---|
true | 현재 View가 이벤트를 처리하고 더 이상 전파하지 않음 | 이벤트 중단 |
false | 현재 View가 이벤트를 처리하지 않음, 상위 View로 전달됨 | 이벤트 전파 |
return true: 이벤트 소비 (Stop Propagation)override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("Touch", "손가락이 닿음")
return true // 이벤트 소비
}
MotionEvent.ACTION_MOVE -> Log.d("Touch", "손가락 움직임")
MotionEvent.ACTION_UP -> Log.d("Touch", "손가락 뗌")
}
return true
}
✅ 결과:
View에서 이벤트를 소비(처리) 하므로 다른 뷰로 이벤트가 전달되지 않음.ACTION_DOWN을 true로 반환하면 이후의 ACTION_MOVE, ACTION_UP도 해당 View에서 처리됨.return false: 이벤트 전달 (Pass Event to Parent)override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("Touch", "손가락이 닿음")
return false // 이벤트 전달
}
MotionEvent.ACTION_MOVE -> Log.d("Touch", "손가락 움직임")
MotionEvent.ACTION_UP -> Log.d("Touch", "손가락 뗌")
}
return false
}
✅ 결과:
View가 이벤트를 처리하지 않으므로 부모(ViewGroup)나 Activity로 이벤트가 전달됨.ACTION_DOWN이 false를 반환하면 ACTION_MOVE, ACTION_UP도 전달되지 않음.ViewGroup이 onInterceptTouchEvent()에서 이벤트를 가로챌 수도 있음.false vs true 동작 차이 예제true)view.setOnTouchListener { _, event ->
Log.d("Touch", "이벤트 발생: ${event.action}")
true // 이벤트를 소비하여 부모로 전달되지 않음
}
✅ 결과:
ViewGroup이나 Activity로 이벤트가 전달되지 않고 해당 View에서만 이벤트가 처리됨.false)view.setOnTouchListener { _, event ->
Log.d("Touch", "이벤트 발생: ${event.action}")
false // 이벤트를 부모에게 전달
}
✅ 결과:
ViewGroup 또는 Activity의 dispatchTouchEvent()로 전달됨.ViewGroup이 onInterceptTouchEvent()를 사용하면 자식 뷰의 터치 이벤트를 가로챌 수도 있음.ViewGroup 안에 Button이 있는 경우, ViewGroup이 터치 이벤트를 가로채거나 넘길 수 있음.class CustomViewGroup(context: Context, attrs: AttributeSet?) : ViewGroup(context, attrs) {
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
return true // 자식 View(Button)로 이벤트가 전달되지 않음
}
override fun onTouchEvent(event: MotionEvent): Boolean {
Log.d("Touch", "ViewGroup에서 터치 이벤트 처리됨")
return true
}
}
button.setOnTouchListener { _, event ->
Log.d("Touch", "Button 터치 이벤트 발생")
false // 이벤트를 ViewGroup으로 전달
}
✅ 결과 분석:
onInterceptTouchEvent()가 true를 반환하면 자식 뷰(Button)로 이벤트가 전달되지 않음.onTouchEvent()가 true이면 ViewGroup이 이벤트를 처리.false이면 ViewGroup의 부모(Activity)로 이벤트가 전달됨.| 반환 값 | 동작 |
|---|---|
true | 현재 View가 이벤트를 처리하고 부모로 전달되지 않음 |
false | 현재 View가 이벤트를 처리하지 않고 부모(ViewGroup, Activity)로 전달됨 |
🔹 true를 반환하면 이벤트를 해당 View에서만 처리하고 끝남.
🔹 false를 반환하면 이벤트가 상위 뷰(ViewGroup 또는 Activity)로 전달됨.
onTouchEvent()가 기본적으로 false를 반환하는 이유Material3의 컴포넌트(예: Button, Card, TextField 등)는 대부분 터치 이벤트를 직접 소비하지 않고, 제스처 감지기(GestureDetector) 또는 클릭/터치 리스너를 통해 이벤트를 처리합니다. 이 때문에, onTouchEvent()에서 false를 반환하는 것이 일반적입니다.
Material3에서는 다음과 같은 방식으로 터치 이벤트를 처리합니다.
onTouchEvent()에서 false 반환Material3 위젯들은 터치 이벤트를 직접 소비하지 않고, 부모 뷰(ViewGroup)로 전달합니다.GestureDetectorCompat) 를 활용하기 때문입니다.GestureDetectorCompat을 사용하여 클릭, 롱클릭, 스와이프 등의 이벤트를 감지합니다.false를 반환하여 다른 이벤트 리스너(setOnClickListener, setOnLongClickListener)에서 감지하도록 합니다.setOnClickListener())가 최종적으로 이벤트를 처리Button의 경우 onTouchEvent()에서는 false를 반환하지만, setOnClickListener()에서 클릭 이벤트를 처리합니다.View에서 onTouchEvent() 동작아래처럼 일반적인 View는 터치 이벤트를 true로 반환하면 이벤트가 소비됩니다.
class CustomView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
override fun onTouchEvent(event: MotionEvent): Boolean {
Log.d("Touch", "CustomView 터치 이벤트 발생")
return true // 이벤트를 소비하여 부모로 전달되지 않음
}
}
✅ 결과
true를 반환하면 이벤트가 여기에서 소비되고 부모로 전달되지 않습니다.Button에서 onTouchEvent() 동작button.setOnTouchListener { _, event ->
Log.d("Touch", "Button 터치 이벤트 발생")
false // 부모(ViewGroup)로 이벤트 전달
}
✅ 결과
false를 반환하여 부모(ViewGroup)로 이벤트가 전달됨.GestureDetector를 통해 처리됨.false 반환 이유MaterialButton, CardView, TextField 같은 Material3 위젯들은 터치 이벤트를 직접 소비하지 않습니다.GestureDetector 활용GestureDetectorCompat을 사용하여 클릭, 롱클릭을 감지합니다.true로 반환하면 다른 이벤트(onClick, onLongClick)가 동작하지 않을 수 있습니다.RecyclerView 안에 있는 MaterialButton이 true를 반환하면 RecyclerView의 스크롤 이벤트가 막힐 수 있습니다.false를 반환하여 부모(RecyclerView, ScrollView 등)에서 추가적인 터치 처리를 할 수 있도록 허용합니다.true 반환)만약 Material3 컴포넌트에서 터치 이벤트를 직접 처리하고 싶다면, setOnTouchListener()에서 true를 반환하면 됩니다.
button.setOnTouchListener { _, event ->
Log.d("Touch", "Material3 버튼 터치 이벤트 발생")
true // 이벤트를 여기에서 소비 (부모로 전달되지 않음)
}
✅ 결과
button에서 소비되며, 상위 ViewGroup으로 전달되지 않음.✔ Material3에서 onTouchEvent()가 기본적으로 false를 반환하는 이유는?
GestureDetector를 사용하여 클릭 & 롱클릭 이벤트를 처리하기 때문📌 만약 특정 위젯에서 터치 이벤트를 직접 처리하고 싶다면 setOnTouchListener()에서 true를 반환하면 된다! 🚀
from. ChatGPT