마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

방금 전에 클릭한 리사이클러뷰의 포지션은 어떻게 가져오는 건가요?

0 추천

리사이클러뷰의 항목마다, 1장, 2장, 3장, 4장.... 이렇게 되어있습니다.

 

장을 선택하면 해당 장만 배경색이 변하여, 내가 지금 어떤 장을 선택하였는지, 배경색으로 쉽게 알아볼 수 있도록 코딩 하려고 합니다.

 

그래서 지금 클릭한 항목의 배경색은 그대로 유지하고,

 

이전에 클릭했던 항목의 배경색을 지워버리고, 클릭할 때마다 이렇게 반복하려고 하는데요.

 

문제는, 리사이클러뷰의 전체 항목정보를 지워버리는 클리어 명령어와 노터피 명령어 밖에 모른다는 점입니다.

 

항목정보를 전부 다 클리어명령어로 지워버리면, 지금 선택한 장의 배경색까지도 클릭하자마자 지워져버립니다. ㅠㅠ

 

어떤 코드로 이전에 선택했던 리사이클러뷰의 포지션들을 불러올 수 있는지 모르겠습니다. ㅠㅠ 조건문을 어떻게 해줘야 할는지도

 

감도 안옵니다.

override fun onBindViewHolder(holder: NumberViewHolder, position: Int) {
     holder.number.text = dataSet[position] 

     if (tandf.get(position, false)) {
          holder.itemView.setBackgroundColor(0x4d00FF7B)
     } else {
          holder.itemView.setBackgroundColor(0x000000)
     }
      
}


//여기에는 키와 값의 형태로, position값과 true false가 함께 저장되는 형식이다. 리사이클러뷰의 각 버튼마다 선택된 상태인지 해제된 상태인지를 저장해주는 코드다. 설정된 기본값은 true다.
private val tandf = SparseBooleanArray(0)



inner class NumberViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {      //이너클래스는 마치 자신이 속한 클래스의 바깥에 정의해놓은 클래스 처럼 행동하는 것이다.
            val number = itemView.findViewById(R.id.textView111) as TextView           //텍스트뷰를 객체화시켜 number변수에 대입했다. 왜냐하면 이 텍스트뷰 객체를 사용하려고 하기 때문이다.


            //리사이클러뷰의 아이템 뷰가 클릭된 위치(포지션)를 찾아내서, 해당 포지션에 클릭 이벤트를 설정해주는 코드다.
            init {
                itemView.setOnClickListener(object : View.OnClickListener {           //리사이클러뷰에 있는 어떤 버튼을 클릭했을때, 어떤 행동을 해주기 위한 내용을 담는 껍데기.
                    override fun onClick(v: View) {
                        val pos = adapterPosition           //리사이클러뷰에 각 항목들의 인덱스 번호, 클릭 이벤트가 일어난 버튼의 인덱스 번호다.
                        if (pos != RecyclerView.NO_POSITION) {      // 항목 삭제, 재활용 때를 위해 꼭 코딩 해줘야 하는 조건
                            //dataSet[pos] = "item clicked. pos=$pos"         //배열 데이터 집합인 list1을 클릭했을 때, pos(인덱스)에 해당하는 버튼에, 어떻게 행동할지에 대한 데이터를 주는 코드
                            if (mListener != null) {
                                mListener!!.onItemClick(v, pos)
                            }





                            if (tandf.get(pos, false)) {
                               
                                tandf.remove(pos, true)
                                notifyDataSetChanged()
                                tandf.put(pos, false)

                            } else {

                                tandf.put(pos, true)
                                v.setBackgroundColor(0x4d00FF7B/*Color.BLUE*/)

                            }


                        }
                    }
                })
            }
        }   

 

위의 코드를 아래 첨부한 코드들과 같이 변경하였더니, 성공하였습니다.

override fun onBindViewHolder(holder: NumberViewHolder, position: Int) {        //position 매개변수는 getItemCount()에서 받아오는 것이고, 받아오기전에 dataSet항목의 총 개수인 dataSet.size를 대입하여 얻어내는 것이다.
            holder.number.text = dataSet[position]          //객체화한 텍스트뷰를 onBindViewHolder에 대입한 후, 1~50까지의 데이터를 집어넣는 코드다.

            if (tandf.get(position, false)) {
                holder.itemView.setBackgroundColor(0x4d00FF7B)
            } else {
                holder.itemView.setBackgroundColor(0x000000)
            }

            holder.mitemView.setOnClickListener(object : View.OnClickListener {
                override fun onClick(v: View?) {
                    if (tandf.get(position, false)) {
                        tandf.put(position, false)
                    } else {
                        tandf.clear()
                        notifyDataSetChanged()
                        tandf.put(position, true)
                        holder.mitemView.setBackgroundColor(0x4d00FF7B/*Color.BLUE*/)
                    }
                    if (mListener != null) {
                                mListener!!.onItemClick(v, pos)
                    }
                }
            })


                  //dataSet.size, nuber.text는 모두 호출되는 것이다. onBindViewHolder()는 호출되는게 아니라, 뷰홀더 클래스와 getItemCont함수를 호출해오는 함수다.
        }


        //여기에는 키와 값의 형태로, position값과 true false가 함께 저장되는 형식이다. 리사이클러뷰의 각 버튼마다 선택된 상태인지 해제된 상태인지를 저장해주는 코드다. 설정된 기본값은 true다.
private val tandf = SparseBooleanArray(0)
        //리사이클러뷰는 아이템 클릭 이벤트 리스너를 자신이 직접 다루지 않고, "뷰홀더 클래스가 갖고 있는 아이템 뷰"에서 OnClickListener를 통해 처리하게 만들어놓았습니다.
        //어댑터 클래스를 통해 만들어진 각 아이템 뷰는 "뷰홀더"객체에 저장되어 화면에 표시되고, 필요에 따라 생성 또는 재활용(Recycle)됩니다.
        //아이템 뷰에서 클릭 이벤트를 직접 처리하고,
        //아이템 뷰는 뷰홀더 객체가 가지고 있으니,
        //아이템 클릭 이벤트는 뷰홀더에서 작성.
inner class NumberViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {      //이너클래스는 마치 자신이 속한 클래스의 바깥에 정의해놓은 클래스 처럼 행동하는 것이다.
      val number = itemView.findViewById(R.id.textView111) as TextView           //텍스트뷰를 객체화시켜 number변수에 대입했다. 왜냐하면 이 텍스트뷰 객체를 사용하려고 하기 때문이다.
      val mitemView = itemView

            //리사이클러뷰의 아이템 뷰가 클릭된 위치(포지션)를 찾아내서, 해당 포지션에 클릭 이벤트를 설정해주는 코드다.
      init {
                itemView.setOnClickListener(object : View.OnClickListener {           //리사이클러뷰에 있는 어떤 버튼을 클릭했을때, 어떤 행동을 해주기 위한 내용을 담는 껍데기.
                    override fun onClick(v: View) {
                        val pos = adapterPosition           //리사이클러뷰에 각 항목들의 인덱스 번호, 클릭 이벤트가 일어난 버튼의 인덱스 번호다.
                        if (pos != RecyclerView.NO_POSITION) {      // 항목 삭제, 재활용 때를 위해 꼭 코딩 해줘야 하는 조건
                            //dataSet[pos] = "item clicked. pos=$pos"         //배열 데이터 집합인 list1을 클릭했을 때, pos(인덱스)에 해당하는 버튼에, 어떻게 행동할지에 대한 데이터를 주는 코드
                           
                        }
                    }
                })
            }
        }       

 

상쾌한 (1,890 포인트) 님이 2021년 1월 19일 질문
상쾌한님이 2021년 1월 20일 수정

1개의 답변

+1 추천
 
채택된 답변
onBindViewHolder 내에서 onClickListener를 추가하면 됩니다.

만약에 RecyclerView 외부의 무언가를 바꾸려 한다면,
바꿀 UI 객체를 RecyclerView 생성자에서 받아서,
onBindViewHolder내에서
처리하면 됩니다.
위에서 처럼 전체 뷰를 클릭할 거라면,
전체 뷰를 val number 하단에 선언하고,
val mItemView = view

onBindViewHolder 안에서

mItemView.setOnClickListener( ~~)

이렇게 정의하면 됩니다.

viewholder 안에 있는 객체들은 viewHolder 내에서 매핑을 하고,
onBindViewHolder에서 핸들링 하면 됩니다.
Will Kim (43,170 포인트) 님이 2021년 1월 20일 답변
상쾌한님이 2021년 1월 20일 채택됨
아 선택하지 않은 것의 배경을 처리해야겠네요.
테스트해 볼 시간은 없어서 아래 링크로 대체합니다.

https://stackoverflow.com/questions/63447284/kotlinchange-background-color-of-recyclerview-item-by-click-on-it
^^ 감사합니다. 지금 한 번 읽어보겠습니다. 선택하지 않은 것의 배경처리는 저 위의 코드만으로도 이미 성공 했음을 확인했습니다. 섬세하신 배려에 감사합니다. ^^ 일단 말씀해주신대로 해보고 오겠습니다. 그리고 리사이클러뷰 외부에서 작업하려 했던 것은 이미 완성해 놓은것이라 그것은 괜찮습니다. 온바인드에 선언해보니 단 번에 완성되었습니다. 너무나도 감사하고, 매 번 감사합니다. 하나님께서 함께하여 주시기를 복내려주시기를 기도하였습니다. 아멘. 제게 도움을 주셔서 매사에 형통케 하셨으므로, 윌킴님 께서도 범사에 형통하시기를 원합니다. ^^ 성공한 코드는 본문 밑에 붙여넣기 하겠습니다. ^^
...