카테고리 없음

2-1. 리싸이클러뷰의 아이템에 컨텍스트 메뉴를 사용하여 메모 삭제

잘할수있을거야 2021. 9. 23. 23:04

리싸이클러뷰의 각 메모에 해당하는 itemView들에 컨텍스트 메뉴를 사용하여 롱 클릭시 SQLite에 접근하여 메모에 해당하는 Row를 삭제

 

컨텍스트 메뉴 사용법 - 2021.09.18 - [Android/UI] - [Android] Context Menu - 사용법 1

 

 

View를 롱 클릭할때 View에 setOnCreateContextMenuListener로 등록된 리스너의 메서드가 호출되며 해당되는 내용에 맞게 컨텍스트 메뉴가 생성된다.

onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?)

 

아이템을 선택하면 Activity에 정의한 onContextItemSelected 메서드가 호출되며 선택된 아이템을 분기시켜 해당되는

동작이 수행된다.

onOptionsItemSelected(item: MenuItem): Boolean

컨텍스트 메뉴 안의 메모 삭제에 해당하는 메뉴 아이템을 누르면 메모가 삭제되어야 하고, 메모가 삭제되기 위해서는 

메모에 해당하는 SQLite의 rowid가 필요했다. 

 

onOptionsItemSelected의 파라메터에서 View를 받을 수 없기 때문에 View의 setTag로 rowId Integer인스턴스를 설정하고 getTag를 통해 받아오려면 View가 필요해야 할 것 같았다.

 

그러나 리싸이클러뷰의 아이템뷰들은 메모개수만큼 만들어지지 않고 재활용되기 때문에 이렇게 할 수 없었다.

 

메뉴에 메뉴 아이템을 추가할 때 메뉴 아이템의 groupId설정을 메모에 해당하는 rowid를 사용하는 트릭을 사용한다.   

메뉴 아이템이 선택되었을 때 onOptionsItemSelected의 item의 그룹아이디 int값( SQLite의 rowid가 설정되어있음)을 통해 DB의 row를 삭제한다. 

 

ViewHolder가 생성되면 (자바 new ViewHolder() ) ViewHolder안에서 itemView를 마음대로 사용할 수 있다.

이것을 몰라서 onBindViewHolder에 파라메터가 ViewHolder만 있어 itemView를 사용하지 못하는 줄알고 지대로 삽을 파고 있었다.

 

그렇기 때문에 RecyclerViewAdapter의 onBindViewHolder 메서드에서도 ViewHolder의 멤버 itemView를 가지고itemView에 관한 작업을 할 수 있게된다.

onBindViewHolder에서 포지션에 맞는 메모리스트[포지션]을 통해 bind메서드에서 컨텍스트 메뉴 리스너를 등록하였다.

 

 

리싸이클러뷰 어댑터

class AdapterMemoList(val context: Context, var memos: List<Memo>) :
    RecyclerView.Adapter<AdapterMemoList.Holder>() {

    //RecyclerView.Adapter
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
        val view = LayoutInflater.from(context).inflate(R.layout.recycler_item_memo, parent, false)
        return Holder(view)
    }

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.bind(memos[position])
    }

    override fun getItemCount(): Int {
        return memos.size
    }

    //RecyclerView.ViewHolder
    inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val title = itemView.findViewById<TextView>(R.id.tv_title)
        val createdDate = itemView.findViewById<TextView>(R.id.tv_createdDate)
        val createdTime = itemView.findViewById<TextView>(R.id.tv_createdTime)


        fun bind(memo: Memo) {
            title.text = memo.title
            createdDate.text = memo.created?.substring(0, 10)
            createdTime.text = memo.created?.substring(11, 19)


            itemView.setOnCreateContextMenuListener(object : View.OnCreateContextMenuListener {

                override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
                    if ((menu != null) && (v != null)) {
                        //menu item's groupid에 rowid를 넣어 설정
                        //groupid, itemid, order, string
                        menu.add(memo.id, 1, Menu.NONE, "삭제")
                    }
                }

            })

            itemView.setOnClickListener {
                val intentToMemoActivitiy=Intent(context, MemoActivity::class.java)
                intentToMemoActivitiy.putExtra("rowid",memo.id)
                intentToMemoActivitiy.putExtra("title",memo.title)
                intentToMemoActivitiy.putExtra("content",memo.content)
                context.startActivity(intentToMemoActivitiy)
            }

        }

    }
    .....나머지 코드

 

액티비티의 onContextItemSelected 

//when menu items selected
    override fun onContextItemSelected(item: MenuItem): Boolean {
        val selectedRowId: Int = item.groupId
        if (selectedRowId != null) {
            when (item.itemId) {
                1 -> {
                    mViewModel.deleteSingleMemo(selectedRowId)
                }
            }
        }
        return true
    }