ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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
        }

     

     

    댓글

Designed by Tistory.