지난번엔 RecyclerView 개념에 대해 알아봤는데, 오늘은 사용 방법을 정리해보려고한다!
정말 자주쓰지만 매번 헷갈려서 이번 기회에 외워놔야겠음... 🥺
dependencies {
// recyclerview
implementation 'androidx.recyclerview:recyclerview:1.2.1'
}
recyclerView 도 gradle 설정이 필요하다! 앱 수준의 gradle 에 추가를 해줌미다.
recyclerview 는 목록을 띄워주는 컨테이너인데, 먼저 그 목록들을 만들어줘야한다. 어차피 틀은 똑같고 내용만 달라지는 거니까 틀만 만들어주면 됩니다잉.
character_item_view.xml
(이건 각자 만들기 나름이니 코드는 생략!)
캐릭터들의 사진, 이름, 좋아하는 것을 보여주는 뷰를 만들었다.
나는 사진, 이름, 좋아하는 것 정보 3가지를 전달할 거라서 따로 클래스로 만들어버렸다!
class Profile(
val image: Int,
val name: String,
val favorite: String
)
image 변수에는 사진의 id 값이 들어갈 예정!
화면과 화면에 나타낼 데이터를 연결짓는 역할을 한다. 얘가 가장 중요한 부분! ✨ 이라서 매번 헷갈릠,,
class CharacterListAdapter(private val dataSet: MutableList<Profile>) : RecyclerView.Adapter<CharacterListAdapter.ViewHolder>() {
private lateinit var binding: CharacterItemViewBinding
inner class ViewHolder(private val binding: CharacterItemViewBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(profile: Profile) {
binding.apply {
image.setImageResource(profile.image)
name.text = profile.name
favorite.text = profile.favorite
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CharacterListAdapter.ViewHolder {
binding = CharacterItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: CharacterListAdapter.ViewHolder, position: Int) {
holder.bind(dataSet[position])
}
override fun getItemCount(): Int {
return dataSet.size
}
}
우선! recyclerView 에 보여줄 데이터 셋을 인자로 전달한다.
inner class ViewHolder()
~ 이 부분을 보면,
CharacterListAdapter 라는 클래스 안에 클래스를 선언해 커스텀 ViewHolder 를 만들어주었다.
데이터를 전달하면, image (ImageView) 에는 이미지를 넣고, name (TextView) 에는 이름 정보, favorite(TextView) 에는 좋아하는 것 정보를 착착 넣어주는 역할을 한다.
함수를 하나씩 살펴보자!
onCreateViewHolder() : ViewHolder 를 생성한다. xml 에서 작성한 화면을 실제로 만들어주는 부분이라고 생각하면 될 것 같다 (? 아마도..)
onBindViewHolder() : onCreateViewHolder() 에서 만든 ViewHolder 와 데이터를 연결한다. (특정 위치에 데이터를 표시한다)
첫번째 데이터는 첫번째 칸에 넣고 열번째 데이터는 열번째 칸에 넣고 .. !
참고할 점은, ListView 와 달리 데이터의 item 들의 위치가 변경되어도 다시 호출되지 않기 때문에 이 함수에 관련된 item 을 가져올때만 position
파라미터를 사용해야한다!
바인딩 = 뷰를 데이터에 연결하는 프로세스
라고 하는데! 화면에 데이터를 쏙쏙 넣어주는 거라고 생각하면 될듯!
getItemCount() : 인자로 전달받은 데이터의 크기를 반환한다.
RecyclerView 가 보여질 화면에
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp" />
다음과 같이 RecyclerView 를 추가한다.
아까 만든 Adpater 를 화면에 보여줄 RecyclerView 에 연결시켜줘야한다. 그래야 내가 만든 데이터 순서에 맞게 RecyclerView 가 착착착 보여지겠지?
의 순서로 하면 된다.
characterListAdapter = CharacterListAdapter(dataSet = dataSet)
binding.recyclerView.adapter = characterListAdapter
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
리스트에 보여줄 데이터를 인자로 전달하고 (위 코드에서는 dataSet
)
adpater 를 지정한다.
LayoutManager 는 리스트를 세로로 보여줄지, 가로로 보여줄지, grid 형식으로 보여줄지 설정할 수 있도록 도와주는데! 나는 세로로 보여줄거라 따로 설정은 안했다.
LayoutManager 를 설정하고 싶다면
가로 설정
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
세로 설정
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
Grid 설정
binding.recyclerView.layoutManager = GridLayoutManager(requireContext(),2)
Grid 설정에서 두 번째 인자는 spanCount 인데, 몇 줄로 보여줄건지를 설정한다.
결과는 다음과 같다
Data 를 변경해서 보여주고 싶다면 ? ?
dataSet.clear()
dataSet.addAll(dataSet2)
//characterListAdapter.notifyItemRangeChanged(0,5)
characterListAdapter.notifyDataSetChanged()
1️⃣ 이전에 만들어놨던 데이터를 밀어버리고 2️⃣ addAll() 로 다른 데이터를 추가하면된다.
3️⃣ 그리고! notifyDataSetChanged()
로 데이터가 변경됐음을 알려줘야한다!
찾아보니, 이 함수는 RecyclerView 를 다시 그리는 거라서 cost 가 굉장히 크다고 하다.
=> 주석 처리 해놓은 notifyItemRangeChanged() 으로 변경된 범위만 update 하면 더 효율적으로 처리할 수 있다!
Main Fragment
를 클릭하면 순서를 바꾼 데이터로 보여주도록 해보았다.
끗!🎉