안드로이드 RecyclerView 빈공간 클릭 이벤트?
조회수 1379회
RecyclerView 아이템을 클릭했을때의 이벤트가 아닌
RecyclerView 의 빈공간을 클릭했을때 이벤트를 잡고 싶어서 (RecyclerView의 크기는 전체로 잡았습니다)
RecyclerView 에 setOnClickListener를 해봤지만 빈공간 클릭했을때 이벤트를 잡을수가 없네요
혹시 RecyclerView의 아이템이 아닌 빈공간을 클릭했을때 이벤트를 받을수 없을까요?
리니어레이아웃으로 감싸고 그 리니어레이아웃에서 setOnClickListener를 해봤지만 리니어레이아웃에서 클릭이벤트를 받을려면 리니어 안의 뷰가 없어야 된다고 하더라고요
아 참고로 RecyclerView 의 아이템 클릭 이벤트와 롱 클릭 이벤트도 받아서 처리 하고 있습니다
감사합니다^
-
(•́ ✖ •̀)
알 수 없는 사용자
1 답변
-
클릭 이벤트는 View 에서 지원하는 기본적인 기능으로써 생각 할 수 있습니다.
RecyclerView
는ViewGroup
을 extend 하고,ViewGroup
은View
를 extend 합니다. 결론적으로, 클릭 이벤트가 View 클래스에서 처리되기 때문에 터치이벤트가 최상위 클래스인 View 까지 전달 되어야 클릭 이벤트를 사용할 수 있다 라고 정리 할 수 있습니다.RecyclerView 코드를 보면, 터치 이벤트를 처리하는
onInterceptTouchEvent
와onTouchEvent
에서scroll
에 대한 동작과OnItemTouchListener
에 대한 동작을 처리하고 super 클래스의 메소드 호출은 하지 않고 있습니다. 따라서 클릭 이벤트 자체가 발생하지 않기 때문에 setOnClickListener 를 설정하여도 onClick 이 호출 되지 않습니다.RecyclerView 자체에 클릭 이벤트를 등록하는 것이 일반적인 경우는 아니지만, 아래와 같이 처리 할 수 있을 것 같습니다.
class TestRecyclerView(context: Context?, attrs: AttributeSet?) : RecyclerView(context, attrs) { private var clickTriggerRunnable: ClickTriggerRunnable? = null private val touchSlop: Int = ViewConfiguration.get(context).scaledTouchSlop private var touchStartPointX = 0.0f private var touchStartPointY = 0.0f override fun onTouchEvent(e: MotionEvent?): Boolean { e?.run { when (action) { MotionEvent.ACTION_DOWN -> { touchStartPointX = x touchStartPointY = y //클릭 이벤트 처리를 위한 runnable 실행 clickTriggerRunnable = ClickTriggerRunnable() handler.postDelayed(clickTriggerRunnable, ViewConfiguration.getTapTimeout().toLong()) } MotionEvent.ACTION_MOVE -> { val deltaX = Math.abs(touchStartPointX - x) val deltaY = Math.abs(touchStartPointY - y) //클릭에 대한 터치 영역을 벗어날 경우 callback 취소 clickTriggerRunnable?.let { if (deltaX > touchSlop || deltaY > touchSlop) { handler.removeCallbacks(clickTriggerRunnable) clickTriggetRunnable = null } } } MotionEvent.ACTION_UP -> { clickTriggerRunnable?.let { val triggered = it.isClickTriggered handler.removeCallbacks(it) clickTriggerRunnable = null return when { triggered -> { //여기에 원하는 클릭 동작을 구현 true } else -> super.onTouchEvent(this) } } } else -> super.onTouchEvent(e) } } return super.onTouchEvent(e) } inner class ClickTriggerRunnable : Runnable { var isClickTriggered = false override fun run() { isClickTriggered = true } } }
-
(•́ ✖ •̀)
알 수 없는 사용자
-
댓글 입력