[문제 상황]
안드로이드 스튜디오에서 kotlin으로 일정 관리 앱을 개발 중이었다.
Recycler View에서 item을 클릭했을 때 하단에서 SlidingUpPanelLayout이 아이템별로 다르게 나타나게 했다.
recycler view에 터치 리스너를 달아서 아이템 클릭 이벤트를 intercept 하는 방식으로 터치 리스너를 구현하고 있었는데,
item 클릭 시 sliding layout이 나타나지 않는 경우 등 제대로 동작하지 않는 것 같아서 Log를 찍어보았다.
[Log 기록 확인]
addOnItemTouchListener(object : RecyclerView.OnItemTouchListener{
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
val child = rv.findChildViewUnder(e.x, e.y)
if (child != null) {
val position = rv.getChildAdapterPosition(child)
Log.d("position","$position")
아이템 클릭 시 제대로 position 값을 적용 하는지 확인하기 위해서 Log 기록을 확인했다.
원하는 대로 동작은 하지만 한번 클릭에 intercept 리스너가 2번씩 호출 된 것을 확인했다.
이를 위한 해결 방법이 필요했다.
[해결 방안]
이전에 인스타그램 클론코딩을 진행할 때 이미지 뷰를 확대하는 코드를 작성한 적이 있었는데,
줌 인을 구현하기 위해서 터치 이벤트를 공부한 적이 있었다.
터치 이벤트 중에서는 손가락이 화면에 닿았을때, 떨어졌을 때 두가지 이벤트 감지가 있었는데,
Recycler View에서 item을 클릭 할 때 두 가지 이벤트가 모두 감지되어서 두번 호출 되는 것 같았다.
이는 MotionEvent에 관한 ACTION 조건과 관련이 있는 것 같아서 관련 안드로이드 개발 문서를 확인했다.
MotionEvent | Android Developers
해결 방법은 터치 리스너 동작 시 ACTION_DOWN (화면에 손가락이 닿음) 이벤트 일 때만 인터셉트하고,
ACTION_UP (화면에서 손가락이 떨어짐) 이벤트 일 때는 동작하지 않도록 하는 것이였다.
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
if (e.action == MotionEvent.ACTION_DOWN) {
val child = rv.findChildViewUnder(e.x, e.y)
if (child != null) {
val position = rv.getChildAdapterPosition(child)
Log.d("position", "$position")
Intercept Event 내부에 화면에 손가락이 처음 닿았을 경우에만 이벤트가 발생하도록 작성했다.
정상적으로 문제를 해결했다.