2-1. 리싸이클러뷰의 아이템에 컨텍스트 메뉴를 사용하여 메모 삭제
리싸이클러뷰의 각 메모에 해당하는 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
}