-
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 }