📌 학습 목표
- ListView를 무엇인지 이해하고 사용할 수 있다.
- Adapter와 AdapterView의 동작 과정을 설명할 수 있다.
- ListView의 한계점을 이해하고 RecyclerView를 사용할 수 있다.
❓ RecyclerView란
📝 Standard Mission
1. RecyclerView Item에 스위치를 넣고 스크롤했을 때 스위치 ON/OFF가 이상하게 설정되는 문제 해결해보기
- 하나의 스위치만 ON하고 스크롤을 했을 때 ON하지 않은 곳에 체크되는 현상 or 돌아왔을 때 체크가 되어있지 않는 현상을 해결하기
실습을 진행하면서 dataList에 Data를 1~30까지 add 해주었고 1, 2, 3 스위치에만 ON을 해주었다. 그러나 1, 2, 3을 제외한 15, 18, 28 같이 이상한 곳에도 ON이 되는 것을 볼 수 있다. 아래와 사진과 같은 현상을 해결하는 것이 이번 첫 번째 과제다!
❓ 원인은
이는 RecyclerView에서 스크롤하면 아이템 뷰를 재사용하기 때문에 발생하는 문제라고 생각했다.
❓ 해결 방법은
아래의 두 가지 방법으로 해결하면 위와 같이 아이템 상태 변화 값을 저장할 수 있다. 방법은 다르나 둘 다 아이템의 위치(position)과 선택 여부(boolean) 값을 저장해서 이를 각 아이템에 연결한다는 원리는 같다.
1. sparseBooleanArray를 활용한다.
2. position과 상태를 저장할 변수를 가진 데이터 클래스를 이용한다.
나는 여기서 sparseBooleanArray를 활용하는 첫번째 방법을 선택했다.
먼저, 아래 코드를 어댑터에 추가해준다. SparseBooleanArray는 정수 값들을 boolean 값들로 매핑시키는 기능을 하는 클래스이다.
다음으로, 어댑터의 ViewHolder 객체에 스위치 상태 값을 추가해준다.
정수 값은 RecyclerView 아이템의 위치(position)로 사용되고, boolean 값은 선택(Checked) 여부로 사용된다. SparseBooleanArray의 get() 함수를 이용해서 인자로 입력되는 position의 상태가 Checked인지 확인할 수 있다.
❗최종 어댑터 코드
package com.example.homework5
import android.util.SparseBooleanArray
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.homework5.databinding.ItemDataBinding
// Adapter 인자에 데이터를 넣어주면, MainActivity 에서 수정하면 자동으로 수정됨
class DataRVAdapter(private val dataList: ArrayList<Data>): RecyclerView.Adapter<DataRVAdapter.DataViewHolder>() {
private val checkboxStatus = SparseBooleanArray()
// ViewHolder 객체
inner class DataViewHolder(private val viewBinding: ItemDataBinding): RecyclerView.ViewHolder(viewBinding.root) {
fun bind(data: Data) {
viewBinding.tvTitle.text = data.title
viewBinding.tvDesc.text = data.desc
viewBinding.switchData.isChecked = checkboxStatus[adapterPosition]
viewBinding.switchData.setOnClickListener {
if (!viewBinding.switchData.isChecked)
checkboxStatus.put(adapterPosition, false)
else
checkboxStatus.put(adapterPosition, true)
notifyItemChanged(adapterPosition)
}
}
}
// ViewHolder 만들어질 때 실행할 동작
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataViewHolder {
val viewBinding = ItemDataBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return DataViewHolder(viewBinding)
}
// ViewHolder가 실제로 데이터를 표시해야 할 때 호출되는 함수
override fun onBindViewHolder(holder: DataViewHolder, position: Int) {
holder.bind(dataList[position])
}
// 표현할 Item의 총 개수
override fun getItemCount(): Int = dataList.size
}
'🍞 대외활동 > Univ Makeus Challenge' 카테고리의 다른 글
[UMC] Android 6주차 워크북 (고급 Layout과 View) (0) | 2022.11.07 |
---|---|
[UMC] Android 5주차 워크북 (RecyclerView) - 메모장 앱 (0) | 2022.10.24 |
[UMC] Android 4주차 워크북 (LifeCycle) (0) | 2022.10.18 |
[UMC] Android 3주차 워크북 (Activity와 Fragment) (0) | 2022.10.15 |
[UMC] Android 2주차 워크북 (Layout) - 유튜브 (0) | 2022.10.02 |