먼저 https://developer.android.com/guide/topics/ui/layout/recyclerview(한글 버전도 있을 겁니다.)를 정독하시구요. Adapter와 ViewHolder를 이해하셔야 해요.
Adapter(어댑터)는 쉬운 예로 파워어댑터는, 110을 220로 변환시켜주잖아요. 한쪽은 110볼트의 소켙에, 다른 한쪽은 220에 연결할 수 있잖아요. 어댑터란 서로 다른 인터페이스의 클래스를 연결시켜주는 역할을 하는 클래스라고 보시면 됩니다.
RecyclerViewHolder는 말그대로 뷰홀더입니다. 컵홀더가 컵을 가지고 있도록 해서 잡아주는 역할을 하듯이, 뷰홀더를 뷰를 가지고 그릴 수 있도록 해줍니다.
RecyclerView에 어떤 형태의 뷰도 출력할 수 있도록 하기위해서 어댑터 클래스를 사용하는 것입니다. 입력에 관계없이 출력을 내맘대로 조절할 수 있도록 말이죠. 그리고 이 어탭터는 실제로 화면에 그리는 실제적인 부분을 뷰홀더에게 맡깁니다. 따라서 뷰홀더가 어떻게 화면에 그리느냐에 따라 실제의 출력이 결정되는 것입니다.
이런 이유로, 어댑터는 여러개의 뷰홀더를 사용할 수 있도록 되어 있습니다. 그래야 뷰의 형태가 다른 것들을 서로 조합해서 하나의 리스트로 보여주기 쉽잖아요. 리스트가 항상 동일한 모양의 뷰만 보여주는 게 아니기 때문에 말이죠.
RecyclerView는 어댑터가 뷰홀더를 이용해 화면을 출력하기 위한 틀에 해당한다고 보시면 됩니다.
RecyclerViewAdapter의 클래스 보시면,
public class RecyclerView.Adapter<VH extends RecyclerView.ViewHolder>
이렇게 정의되어 있습니다. 어떤 뷰홀더를 사용할 것인지 어댑터에게 알려주는 것이죠.
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
private List<String> items;
public CustomAdapter(items: List<String>) {
this.items = items;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.text_row_item, viewGroup, false);
return ViewHolder(view);
}
@Override
public void onBindViewHolder(viewHolder: ViewHolder, position: Int) {
viewHolder.textView.text = items.get(position);
}
@Override
public int getItemCount() {
return items.getSize();
}
class ViewHolder(view: View) extends RecyclerView.ViewHolder(view) {
public final val textView: TextView
public ViewHolder(View itemView) {
textView = view.findViewById(R.id.textView)
}
}
}
어댑터를 구현하실 때는, 먼저 RecyclerView.Adapter를 상속하셔야 합니다. 그리고 뷰홀더 클래스를 만드셔서 해당 클래스를 제너릭 타입으로 넣어주세요.
getItemCount를 오버라드 하셔서, 님이 화면에 뿌려줄 아이템의 갯수를 지정해 주세요. 만약 어댑터에 전달한 아이템 리스트의 갯수만큼 하실 거면 itemList.getSize()라고 하시면 되겠죠.
그리고 해당 아이템을 화면에 그리기 위해서 뷰홀더 클래스를 만들고 이 클래스의 인스턴스를 onCreateViewHolder 메소드에서 해줍니다. 그리고 onBindViewHolder()에서 실제 아이템을 그리는 부분을 구현해 줍니다.onBindViewHolder 메소드에서 첫번째 ViewHolder는 onCreateViewHolder에서 조금 전에 생성했던 인스턴스입니다.
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.text_row_item, viewGroup, false)
return ViewHolder(view)
}
onCreteViewHolder에서는 각각의 아이템의 사용할 레이아웃을 가져와서 이걸 inflate 합니다.뷰에 실제 내용을 보여주는 건 ViewHolder클래스에서 처리하시면 되구요.
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
viewHolder.textView.text = dataSet[position]
}
위에서는 dataSet[position]으로 위에서 생성했던 문자열 리스트를 포지션에 맞게 읽어와서 보여주고 있습니다. 기본 흐름은 이렇구요. 리사이클러뷰의 특징은 뷰의 재사용입니다. 뷰를 메모리에 보관했다가 다시 꺼내어 쓰기위해 ViewHolder를 사용하는 겁니다. 이렇게 하게되면 아이템의 갯수가 많아져도 성능이 많아져도 속도가 확 저하되지는 않습니다.
아마 onCreateViewHolder나 onBindViewHolder에서 ViewHolder 인스턴스를 확인해 보시면, 리사이클러뷰가 뷰를 재상요하는 것을 쉽게 화인할 수 있습니다.
더 자세한 것은 개발자 사이트나 구글에서 적당한 튜토리얼을 찾아보시면 되리라 생각합니다.예제를 많이 짜보세요, 몇번 해보시면 감이 오실 겁니다.