안드로이드 앱에서 리스트 형태의 데이터를 표시하는데 사용되는 위젯. 여러 아이템을 스크롤 가능한 리스트로 표현하며, 많은 아이템을 효율적으로 관리하고 보여주는 역할을 함
사용자가 스크롤 할 때마다 위에 있던 아이템은 삭제되고, 맨 아래의 아이템은 생성 되길 반복
아이템이 100개면 100이 삭제 생성됩니다. 즉 계속 삭제와 생성을 반복하므로 성능에 좋지 않음
사용자가 스크롤 할 때, 위에 있던 아이템은 재활용 돼서 아래로 이동하여 재사용
즉 아이템이 100개여도 10개정도의 View만 만들고 10개를 재활용해서 사용
View를 계속 만드는 ListView의 단점을 보완
Adapter란 데이터 테이블을 목록 형태로 보여주기 위해 사용되는 것으로, 데이터를 다양한 형식의 리스트 형식을 보여주기 위해서 데이터와 RecyclerView 사이에 존재하는 객체
즉 데이터와 RecyclerView 사이의 통신을 위한 연결체
쉽게 생각하면 여행할 때 멀티 어댑터로 나라별 콘센트 변환시키기로 생각!
ViewHolder란 화면에 표시될 데이터나 아이템들을 저장하는 역할
RecyclerView의 개념을 적용하기 위해선 스크롤 해서 위로 올라간 View를 재활용하기 위해서 이 View를 기억하고 있어야 함. ViewHolder가 그 역할을 함
RecyclerView 폴더를 새로 만들고 이전에 실습한 CustomItemView 복사
AndroidStudioFile > Open을 눌러 RecyclerView 폴더를 엶
메인화면 레이아웃(예,activity_main.xml)에 ListView 위젯을 RecyclerView 위젯으로 변경
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
앞서 정의한 MyItem 타입의 객체들을 ArrayList로 관리하는 MyAdapter 클래스를 RecyclerView.Adapter를 파생하여 정의
MyAdapter.kt
class MyAdapter(val mItems: MutableList<MyItem>) : RecyclerView.Adapter<MyAdapter.Holder>() {
interface ItemClick {
fun onClick(view : View, position : Int)
}
var itemClick : ItemClick? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val binding = ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return Holder(binding)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.itemView.setOnClickListener { //클릭이벤트추가부분
itemClick?.onClick(it, position)
}
holder.iconImageView.setImageResource(mItems[position].aIcon)
holder.name.text = mItems[position].aName
holder.age.text = mItems[position].aAge
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount(): Int {
return mItems.size
}
inner class Holder(val binding: ItemRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root) {
val iconImageView = binding.iconItem
val name = binding.textItem1
val age = binding.textItem2
}
}
MyItem.kt
data class MyItem(val aIcon:Int, val aName:String, val aAge:String) {}
MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// 데이터 원본 준비
val dataList = mutableListOf<MyItem>()
dataList.add(MyItem(R.drawable.sample_0, "Bella", "1"))
dataList.add(MyItem(R.drawable.sample_1, "Charlie", "2"))
dataList.add(MyItem(R.drawable.sample_2, "Daisy", "1.5"))
dataList.add(MyItem(R.drawable.sample_3, "Duke", "1"))
dataList.add(MyItem(R.drawable.sample_4, "Max", "2"))
dataList.add(MyItem(R.drawable.sample_5, "Happy", "4"))
dataList.add(MyItem(R.drawable.sample_6, "Luna", "3"))
dataList.add(MyItem(R.drawable.sample_7, "Bob", "2"))
val adapter = MyAdapter(dataList)
binding.recyclerView.adapter = adapter
binding.recyclerView.layoutManager = LinearLayoutManager(this)
adapter.itemClick = object : MyAdapter.ItemClick {
override fun onClick(view: View, position: Int) {
val name: String = dataList[position].aName
Toast.makeText(this@MainActivity," $name 선택!", Toast.LENGTH_SHORT).show()
}
}
}
}
실행 결과