<Android>RecyclerView 아이템 클릭 시 Context Menu를 띄워보기

진섭·2023년 6월 16일
0

Android

목록 보기
19/31
post-thumbnail

🔨 개요

오늘 RecyclerView에서 아이템을 클릭했을 때 Context Menu를 보이고 아이템을 삭제를 해주고 싶었는데 생각보다 구현하기가 어려워서 블로그에 기록하기로 마음을 먹었습니다.
제가 어려웠던 부분은 Context Menu를 띄웠는데 삭제 메뉴를 누르면 NullPointerException 에러가 뜨고 이 오류를 해결해도 아이템이 그대로 있었습니다.

구글 검색을 통해 RecyclerView는 ViewHolder안에서 View.OnCreateContextMenuListener 인터페이스를 추가해 onCreateContextMenu 메서드를 구현해줘야 한다는 사실을 알았습니다. 다행히 이 힌트를 얻고 제가 원하는 기능을 구현할 수 있게 되었고 제가 이 힌트를 얻기 전에는 ViewHolder 밖에서 구현해 줘서 아무 변화가 없었던 거 같아요.

🔨 Context Menu란?

사용자가 특정 항목이나 뷰를 길게 클릭할 때 나타나는 메뉴입니다. 카카오톡 채팅방을 길게 누르면 채팅방 이름 설정, 채팅방 상단 고정 등 메뉴가 뜨는데 이게 바로 Context Menu입니다.

🔨 Context Menu 만들어 보기

🔨1. 특정 항목이나 뷰를 길게 눌렀을 때 보여줄 메뉴 만들기

res -> menu -> conntext_menu.xml (menu 폴더 New Resoure Directiry로 생성합니다. )

menu 안에 item을 만들어줍니다.

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/itemDelete"
        android:title="항목삭제" />
</menu>

🔨 2. RecyclerView ViewHolder

  • RecyclerView ViewHolder View.OnCreateContextMenuListener를 인터페이스를 추가해 콜백 메서드인 onCreateContextMenu를 구현해줍니다.
  • init 블록에서는 ViewHolder 인스턴스를 ContextMenu를 등록합니다.
  • onCreateContextMenu 구현부에서는 ContextMenu를 생성하고 보여주는 역할을 합니다.
  • 이 메서드안에서 먼저 setHeaderTitle에서는 클릭을 길게 하면 상단에 해당 위치에 해당하는 값을 제가 만든 객체에서 가져옵니다.
  • 그 밑에는 아까 제가 만든 conntext_menu.xml 에서 만든 항목 삭제 버튼이 들어가 있는 레이아웃을 가리킵니다.
  • 다음으로는 삭제 기능을 구현하는 부분인데 먼저 findItem으로 itemDelete을 찾습니다. 그리고 아이템에 대한 클릭 리스너를 설정하고 { } 안에서 클릭 이벤트가 발생했을 때 부분이 구현됩니다.
  • 안으로 들어가 보면 adapterPosition으로 현재 ViewHolder의 위치를 position 변수에 저장을 먼저 하고
  • position이 유효한 위치인지 확인을 한 다음 해당 위치에 있는 학생 객체를 삭제합니다.
  • RecyclerView.NO_POSITION는 유효하지 않은 상숫값 -1이 들어갑니다. 아이템의 위치가 유효하지 않을 때 이 값으로 설정됩니다.
  • 그리고 notifyItemRemoved(position) 호출하여 어댑터에게 해당 위치의 아이템이 삭제되었음을 알립니다.
inner class AdapterViewHolder(binding: ItemInfoBinding) :
            RecyclerView.ViewHolder(binding.root), View.OnCreateContextMenuListener {
            val nameTextView: TextView = binding.nameTextView
            val ageTextView: TextView = binding.ageTextView
            val korTextView: TextView = binding.korScoreTextView

            init {
                itemView.setOnCreateContextMenuListener(this)
            }

            override fun onCreateContextMenu(
                menu: ContextMenu?,
                v: View?,
                menuInfo: ContextMenu.ContextMenuInfo?
            ) {
                menu?.setHeaderTitle(studentList[adapterPosition].name)
                menuInflater.inflate(R.menu.context_menu, menu)

                menu?.findItem(R.id.itemDelete)?.setOnMenuItemClickListener {
                    val position = adapterPosition
                    if (position != RecyclerView.NO_POSITION) {
                        studentList.removeAt(position)
                        notifyItemRemoved(position)
                    }
                    true
                }

            }

        }

소스코드
https://github.com/kimjinsub1217/App-SCHOOL-Unit-2-Kotlin-Example-of-studying-on-Android/tree/main/android39_ex01

참고사이트
1. https://velog.io/@pass/Context-Menu
2. https://developer.android.com/guide/topics/ui/menus?hl=ko
3. https://velog.io/@chhue/Menu

profile
Android 개발자

0개의 댓글